pretty.cr 
Something pretty
stuff for Crystal.
Pretty.bytes(123456789) # => "123 MB"
Pretty.number(123456789) # => "123,456,789"
Pretty.date("2001-02-03") # => 2001-02-03 00:00:00.0 Local
Pretty.time("2000-01-02 03:04:05.678") # => 2000-01-02 03:04:05 UTC
Pretty.epoch(981173106) # => 2001-02-03 04:05:06 UTC
Pretty.camelize("http_request") # => "httpRequest"
Pretty.classify("http_request") # => "HttpRequest"
Pretty.underscore("a1Id") # => "a1_id"
Pretty.diff(1,2).to_s # => "Expected '1', but got '2'"
Pretty.mem_info.total.gb # => 32.939736
Pretty.method(1.5).call("ceil") # => 2
Pretty.process_info.max.mb # => 3.568
Pretty.version("0.28.0-dev").minor # => 28
Pretty::Crystal.version.minor # => 27
Pretty::Dir.clean("a/b/c") # rm -rf a/b/c && mkdir -p a/b/c
Pretty::Stopwatch.new # provides Stopwatch
# handy linux file operations
include Pretty::File # provides unix file commands via `FileUtil`
rm_f("foo.txt") # cd, cmp, touch, cp, cp_r, ln, ln_s, ln_sf, mkdir, mkdir_p, mv, pwd, rm, rm_r, rm_rf, rmdir
library and crystal versions
- v0.5.7 for crystal-0.24 or lower
- v0.6.x for crystal-0.25, 0.26, 0.27 or higher
breaking changes
- v0.7.0: drop
klass
macro (Do not define unnecessary macros at the top level)
API
Pretty.bytes(value : Int, block = 1000, suffix = "B")
Pretty.camelize(str : String)
Pretty.classify(str : String)
Pretty.date(value : String)
Pretty.error(err : Exception)
Pretty.json(json : String, color : Bool = false)
Pretty.lines(lines : Array(Array(String)), indent : String = "", delimiter : String = "")
Pretty.mem_info
Pretty.method(obj : T).call(name : String)
Pretty.number(n : Int)
Pretty.underscore(str : String)
Pretty::Dir.clean(path : String)
Pretty::Stopwatch.new
Pretty::Time.parse(value : String)
Installation
Add this to your application's shard.yml
:
dependencies:
pretty:
github: maiha/pretty.cr
version: 0.7.1
Then require it in your app.
require "pretty"
Usage
Pretty.bytes(args) : String
Pretty.bytes(416) # => "416 B"
Pretty.bytes(12255736) # => "12.3 MB"
Pretty.bytes(12255736, block: 1024) # => "11.7 MiB"
Pretty.camelize(str) : String
Pretty.camelize("http_request") # => "httpRequest"
Pretty.classify(str) : String
Pretty.classify("http_request") # => "HttpRequest"
Pretty.date : Time
(aka. Pretty::Date.parse(args)
)
Pretty.date("2001-02-03") # => 2001-02-03 00:00:00.0 Local
Pretty.date("1 day ago") # => 2018-09-08 00:00:00.0 +09:00 Local
Pretty.dates : Array(Time)
(aka. Pretty::Date.parse_dates(args)
)
Pretty.dates("20180901") # => [Time(20180901)]
Pretty.dates("20180908-20180909") # => [Time(20180908),Time(20180909)]
Pretty.dates("201809").size # => 30
Pretty.dates("201801-201802").size # => 59
Pretty.diff(a, b) : Pretty::Diff
data1 = [[112433,15,0],[112465,7293,273]]
data2 = [[112433,15,0],[112465,1307,273]]
diff = Pretty.diff(data1, data2)
diff.size # => 1
diff.to_s # => "Expected '7293', but got '1307'"
Pretty.epoch(str) : Time
Absorbs the API difference that changes with each release of crystal.
Personally, epoch
and epoch_ms
are the most intuitive.
Pretty.epoch(981173106) # => 2001-02-03 04:05:06 UTC
Pretty.epoch_ms(981173106789) # => 2001-02-03 04:05:06.789 UTC
Users can always use this API even if crystal API will be changed again in the future.
Pretty.error(err) : Pretty::Error
err.backtrace # => ["0x48df77: *CallStack::unwind:Array(Pointer(Void))
Pretty.error(err).where # => "mysql at src/commands/db.cr 20:3"
IMPORTANT
- We must call app with path for
where
, otherwise the app will be killed.- :x:
foo
# would kill your app in printing backtraces - :o:
/usr/local/bin/foo
# will work
- :x:
Pretty.json(args) : String
str = %({"id": "123", "name": "maiha"})
Pretty.json(str)
{
"id": "123",
"name": "maiha"
}
Pretty.lines(args) : String
array = [
["user", "maiha"],
["password", "123"],
]
Pretty.lines(array, delimiter: " = ")
user = maiha
password = 123
Pretty.mem_info : Pretty::MemInfo
represents memory information in "/proc/meminfo" as Pretty::MemInfo
Pretty.mem_info # => #<Pretty::MemInfo>
Pretty.mem_info.keys # => ["MemTotal", "MemFree", ...]
Pretty.mem_info["MemTotal"] # => Pretty::UsedMemory(@kb=32939736_i64)
Pretty.mem_info.total # => Pretty::UsedMemory(@kb=32939736_i64)
Pretty.mem_info.total.gb # => 32.939736
Pretty::MemInfo.process
returns a MemInfo
of current process.
logger.info "max memory: %s GB" % Pretty::MemInfo.process.max.gb
Pretty.method(obj : T).call(name : String)
invoke method by String
Pretty.method([1,2]).call("pop") # => 2
Pretty.method([1,2]).call?("xxx") # => nil
NOTE
- works only public methods, not trailing equals, defined in itself not ancestors
Pretty.process_info(pid = "self") : Pretty::ProcessInfo
represents memory information in "/proc/*/status" as Pretty::MemInfo
Pretty.process_info # => #<Pretty::ProcessInfo>
Pretty.process_info.keys # => ["VmPeak", "VmSize", ...]
Pretty.process_info["VmPeak"] # => Pretty::UsedMemory(@kb=92644_i64)
Pretty.process_info.max.mb # => 3.568
Pretty.process_info(1234) # Error opening file '/proc/1234/status'
Pretty.number(n) : String
Pretty.number(1000000) # => "1,000,000"
Pretty.version(str) : Pretty::Version
parses numbers separated by dots.
Pretty.version("0.27.2").minor # => 27
This can also sort ip addresses.
hosts = %w( 192.168.10.1 192.168.0.255 )
sorted = hosts.map{|s| Pretty.version(s)}.sort
sorted.map(&.to_s) # => ["192.168.0.255", "192.168.10.1"]
sorted.map(&.last) # => [255, 1]
Pretty::Dir.clean(dir)
acts same as unix command rm -rf dir && mkdir -p dir
.
Pretty::Dir.clean("tmp/work")
Pretty::Time.parse(args) : Time
(aka. Pretty.time
)
parses time without format!
Pretty.time("2000-01-02") # => 2000-01-02 00:00:00 UTC
Pretty.time("2000-01-02 03:04:05") # => 2000-01-02 03:04:05 UTC
Pretty.time("2000-01-02 03:04:05.678") # => 2000-01-02 03:04:05 UTC
Pretty.time("2000-01-02T03:04:05.678+09:00") # => 2000-01-02 03:04:05 +0900
Development
make
Contributing
- Fork it ( https://github.com/maiha/pretty.cr/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- maiha maiha - creator, maintainer