Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sija/any_hash.cr
Better JSON::Any for Crystal
https://github.com/sija/any_hash.cr
crystal data-structures hash json manipulation yaml
Last synced: 11 days ago
JSON representation
Better JSON::Any for Crystal
- Host: GitHub
- URL: https://github.com/sija/any_hash.cr
- Owner: Sija
- License: mit
- Created: 2017-02-07T20:54:22.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2023-10-12T16:33:54.000Z (about 1 year ago)
- Last Synced: 2024-10-25T01:58:46.290Z (19 days ago)
- Topics: crystal, data-structures, hash, json, manipulation, yaml
- Language: Crystal
- Homepage:
- Size: 53.7 KB
- Stars: 35
- Watchers: 5
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# any_hash.cr [![CI](https://github.com/Sija/any_hash.cr/actions/workflows/ci.yml/badge.svg)](https://github.com/Sija/any_hash.cr/actions/workflows/ci.yml)
**AnyHash** is a library created to help with traversing and manipulation of
nested `Hash` structures.## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
any_hash:
github: sija/any_hash.cr
```## Usage
```crystal
require "any_hash"
```### Using `AnyHash::JSON`
`AnyHash::JSON` is ready-to-use JSON friendly version of `Hash`.
It takes care of casting immutable types to their mutable equivalents:
- `Tuple` → `Array`
- `NamedTuple` → `Hash`#### Traversing
```crystal
# possibly coming from `**options` argument, could be a `Hash` too
options = {
status: :published,
tags: {"crystal", "ruby", "sweet"},
context: {
user: {
id: 123,
}
}
}# convert any Hash or NamedTuple to `AnyHash::JSON` via `Object#to_any_json`
options = options.to_any_json# return underlying `Hash`
options.to_h # => {:status => :published, :tags => ["crystal", "ruby", "sweet"], :context => {:user => {:id => 123}}}# access direct descendant value
options[:status] # => :publishedoptions[:status].class # => Symbol
typeof(options[:status]) # => (Array(AnyHash::JSONTypes::Value) | Bool | Float32 | Float64 | Hash(String | Symbol, AnyHash::JSONTypes::Value) | Int16 | Int32 | Int64 | Int8 | Set(AnyHash::JSONTypes::Value) | String | Symbol | Time | UInt16 | UInt32 | UInt64 | UInt8 | Nil)# access nested structures with key path
options[:context, :user, :id] # => 123# `#[]` is an alias for `#dig`, same for `#[]?` -> `#dig?`
options[:context, :system, :os]? # => nil
options.dig?(:context, :system, :os) # => nil
```#### Manipulation
```crystal
# `#[]=` works with single keys and key paths
options[:featured] = true
options[:context, :user, :role] = :editordefaults = {
difficulty: :easy,
status: :draft,
featured: false,
tags: [] of String,
context: {} of Symbol => String
}# merge defaults in-place
options.reverse_merge!(defaults)# or return a copy with applied changes
settings = options.reverse_merge(defaults)# merge nested structures
options.merge! context: {user: {email: "[email protected]"}}# or single values
options.merge! id: 420
```### Defining your own class
```crystal
AnyHash.define_new klass: :DegreesOfLogic,
key: Symbol | String,
value: BoolDegreesOfLogic.new({ there: { are: { many: { truths: true, or: false }}}})
```## Development
Run specs with:
```
crystal spec
```## Contributing
1. Fork it ( https://github.com/sija/any_hash.cr/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create a new Pull Request## Contributors
- [sija](https://github.com/sija) Sijawusz Pur Rahnama - creator, maintainer