Skip to content

Commit

Permalink
Create an abstract Any for JSON/YAML
Browse files Browse the repository at this point in the history
  • Loading branch information
j8r committed Jul 21, 2018
1 parent 1bedce6 commit 1678236
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 353 deletions.
194 changes: 194 additions & 0 deletions src/any.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
abstract struct Any
# Assumes the underlying value is an `Array` or `Hash` and returns its size.
# Raises if the underlying value is not an `Array` or `Hash`.
def size : Int
case object = @raw
when Array
object.size
when Hash
object.size
else
raise "Expected Array or Hash for #size, not #{object.class}"
end
end

# Checks that the underlying value is `Array`, and returns its value.
# Raises otherwise.
def as_a : Array(Any)
@raw.as(Array)
end

# Checks that the underlying value is `Array`, and returns its value.
# Returns `nil` otherwise.
def as_a? : Array(Any)?
@raw.as?(Array)
end

# Checks that the underlying value is `Bool`, and returns its value.
# Raises otherwise.
def as_bool : Bool
@raw.as(Bool)
end

# Checks that the underlying value is `Bool`, and returns its value.
# Returns `nil` otherwise.
def as_bool? : Bool?
@raw.as?(Bool)
end

# Checks that the underlying value is `Float64`, and returns its value.
# Raises otherwise.
def as_f : Float32
as_f64.to_f
end

# Checks that the underlying value is `Float64`, and returns its value.
# Returns `nil` otherwise.
def as_f? : Float32?
as_f64?.try &.to_f
end

# Checks that the underlying value is `Float`, and returns its value as an `Float32`.
# Raises otherwise.
def as_f64 : Float64
@raw.as(Float64)
end

# Checks that the underlying value is `Float`, and returns its value as an `Float32`.
# Returns `nil` otherwise.
def as_f64? : Float64?
@raw.as?(Float64)
end

# Checks that the underlying value is `Nil`, and returns `nil`.
# Raises otherwise.
def as_nil : Nil
@raw.as(Nil)
end

# Checks that the underlying value is `String`, and returns its value.
# Raises otherwise.
def as_s : String
@raw.as(String)
end

# Checks that the underlying value is `String`, and returns its value.
# Returns `nil` otherwise.
def as_s? : String?
@raw.as?(String)
end

# Checks that the underlying value is `Int64`, and returns its value as `Int32`.
# Raises otherwise.
def as_i : Int32
@raw.as(Int64).to_i
end

# Checks that the underlying value is `Int64`, and returns its value as `Int32`.
# Returns `nil` otherwise.
def as_i? : Int32?
@raw.as?(Int64).try &.to_i
end

# Checks that the underlying value is `Int64`, and returns its value.
# Raises otherwise.
def as_i64 : Int64
@raw.as(Int64)
end

# Checks that the underlying value is `Int64`, and returns its value.
# Returns `nil` otherwise.
def as_i64? : Int64?
@raw.as?(Int64)
end

# Checks that the underlying value is `Bytes`, and returns its value.
# Raises otherwise.
def as_bytes : Bytes
@raw.as(Bytes)
end

# Checks that the underlying value is `Bytes`, and returns its value.
# Returns `nil` otherwise.
def as_bytes? : Bytes?
@raw.as?(Bytes)
end

# :nodoc:
def inspect(io)
@raw.inspect(io)
end

# :nodoc:
def to_s(io)
@raw.to_s(io)
end

# :nodoc:
def pretty_print(pp)
@raw.pretty_print(pp)
end

# Returns `true` if both `self` and *other*'s raw object are equal.
def ==(other : Any)
raw == other.raw
end

# Returns `true` if the raw object is equal to *other*.
def ==(other)
raw == other
end

# See `Object#hash(hasher)`
def_hash raw

# Returns a new Any instance with the `raw` value `dup`ed.
def dup
Any.new(raw.dup)
end

# Returns a new Any instance with the `raw` value `clone`ed.
def clone
Any.new(raw.clone)
end
end

macro any_classes(type)
class Object
def ===(other : {{type.id}}::Any)
self === other.raw
end
end

struct Value
def ==(other : {{type.id}}::Any)
self == other.raw
end
end

class Reference
def ==(other : {{type.id}}::Any)
self == other.raw
end
end

class Array
def ==(other : {{type.id}}::Any)
self == other.raw
end
end

class Hash
def ==(other : {{type.id}}::Any)
self == other.raw
end
end

class Regex
def ===(other : {{type.id}}::Any)
value = self === other.raw
$~ = $~
value
end
end
end
Loading

0 comments on commit 1678236

Please sign in to comment.