Skip to content

Commit

Permalink
feat: Add Hash and Json conversion methods to T::Struct (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxveldink authored Feb 27, 2024
1 parent 80f20a9 commit 6df87c2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
20 changes: 20 additions & 0 deletions lib/sorbet-schema/struct_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,25 @@ def self.create_schema
end
)
end

sig { params(hash: Typed::HashSerializer::InputHash).returns(Typed::Serializer::DeserializeResult) }
def self.from_hash(hash)
Typed::HashSerializer.new(schema: create_schema).deserialize(hash)
end

sig { params(json: String).returns(Typed::Serializer::DeserializeResult) }
def self.from_json(json)
Typed::JSONSerializer.new(schema: create_schema).deserialize(json)
end

sig { returns(Typed::HashSerializer::OutputHash) }
def to_hash
Typed::HashSerializer.new(schema: self.class.create_schema).serialize(self)
end

sig { returns(String) }
def to_json
Typed::JSONSerializer.new(schema: self.class.create_schema).serialize(self)
end
end
end
9 changes: 6 additions & 3 deletions lib/typed/hash_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

module Typed
class HashSerializer < Serializer
Input = type_member { {fixed: T::Hash[T.any(Symbol, String), T.untyped]} }
Output = type_member { {fixed: T::Hash[Symbol, T.untyped]} }
InputHash = T.type_alias { T::Hash[T.any(Symbol, String), T.untyped] }
OutputHash = T.type_alias { Params }

Input = type_member { {fixed: InputHash} }
Output = type_member { {fixed: OutputHash} }

sig { override.params(source: Input).returns(Result[T::Struct, DeserializeError]) }
def deserialize(source)
Expand All @@ -17,7 +20,7 @@ def serialize(struct)

private

sig { params(hash: T::Hash[T.any(String, Symbol), T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
sig { params(hash: InputHash).returns(OutputHash) }
def symbolize_keys(hash)
hash.each_with_object({}) { |(k, v), h| h[k.intern] = v }
end
Expand Down
26 changes: 26 additions & 0 deletions test/struct_ext_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
# typed: true

class StructExtTest < Minitest::Test
def setup
@person = Person.new(name: "Max", age: 29)
end

def test_create_schema_is_available
assert_equal(PersonSchema, Person.create_schema)
end

def test_from_hash_works
result = Person.from_hash({name: "Max", age: 29})

assert_success(result)
assert_payload(@person, result)
end

def test_from_json_works
result = Person.from_json('{"name": "Max", "age": 29}')

assert_success(result)
assert_payload(@person, result)
end

def test_to_hash_works
assert_equal({name: "Max", age: 29}, @person.to_hash)
end

def test_to_json_works
assert_equal('{"name":"Max","age":29}', @person.to_json)
end
end

0 comments on commit 6df87c2

Please sign in to comment.