Skip to content

Commit

Permalink
Some new features here and there
Browse files Browse the repository at this point in the history
BusHero committed Oct 10, 2021
1 parent ab4a93a commit 596fdd8
Showing 3 changed files with 113 additions and 5 deletions.
17 changes: 17 additions & 0 deletions Pevac/Pevac.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 29 additions & 3 deletions src/Pevac/Parser/Parser.Object.cs
Original file line number Diff line number Diff line change
@@ -81,16 +81,31 @@ from _ in parser
public static Parser<T> ParseObject<T>(Func<string, Parser<Func<T, T>>> parserSelector, T @default) => parserSelector switch
{
null => throw new ArgumentNullException(nameof(parserSelector)),
not null => from updater in ParseObject(parserSelector)
not null => from updater in ParseObjectProperties(parserSelector)
select updater(@default)
};

/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parserSelector"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static Parser<T> ParseObject<T>(Func<string, Parser<Func<T, T>>> parserSelector) where T: new() => parserSelector switch
{
null => throw new ArgumentNullException(nameof(parserSelector)),
not null => from updater in ParseObjectProperties(parserSelector)
select updater(new T())
};


/// <summary>
/// Parses an object with fields
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Parser<Func<T, T>> ParseObject<T>(Func<string, Parser<Func<T, T>>> parserSelector) => parserSelector switch
public static Parser<Func<T, T>> ParseObjectProperties<T>(Func<string, Parser<Func<T, T>>> parserSelector) => parserSelector switch
{
null => throw new ArgumentNullException(nameof(parserSelector)),
not null => PropertyName
@@ -111,7 +126,18 @@ select updater(@default)
public static Parser<Func<TParent, TParent>> ParseObject<TParent, TChild>(
Func<string, Parser<Func<TChild, TChild>>> parserSelector,
Func<TParent, TChild> cast) where TChild : TParent =>
from updater in ParseObject(parserSelector)
from updater in ParseObjectProperties(parserSelector)
select new Func<TParent, TParent>(parent => updater(cast(parent)));



/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="message"></param>
/// <returns></returns>
public static Parser<Func<T, T>?> FailUpdate<T>(string message = "Some default message") => Failure<Func<T, T>>(message);

}
}
69 changes: 67 additions & 2 deletions tests/Pevac.Tests/ObjectDeserializerTests.cs
Original file line number Diff line number Diff line change
@@ -9,6 +9,18 @@ namespace Pevac.Tests
{
public class ObjectDeserializerTests
{
private record Foo() { }

private record Bar() : Foo
{
public int BarValue { get; set; }
}

private record Baz(): Foo
{
public string BazValue { get; set; }
}

private record Data(string Foo, string Bar)
{
public string Foo { get; set; } = Foo;
@@ -22,6 +34,22 @@ private record SubType(string Foo, string Bar, string Baz): Data(Foo, Bar)
public static SubType Copy(Data data) => new(data.Foo, data.Bar, "");
}

private Parser<Foo> FooParser { get; } = Parser.ParseObject(propertyName => propertyName switch
{
"type" => Parser.String.Updater<string, Foo>(),
"bar" => Parser.ParseObject(propertyName => propertyName switch
{
"bar_value" => Parser.Int32.Updater((int data, Bar bar) => bar.BarValue = data),
_ => Parser.FailUpdate<Bar>()
}, (Foo parent) => new Bar()),
"baz" => Parser.ParseObject(propertyName => propertyName switch
{
"baz_value" => Parser.String.Updater((string data, Baz baz) => baz.BazValue = data),
_ => Parser.FailUpdate<Baz>()
}, (Foo _) => new Baz()),
_ => Parser.FailUpdate<Foo>()
});

[Fact]
public void DeserializeObject()
{
@@ -37,7 +65,7 @@ public void DeserializeObject()
{
"foo" => Parser.String.Updater((string foo, Data data) => data with { Foo = foo }),
"bar" => Parser.String.Updater((string bar, Data data) => data.Bar = bar),
_ => Parser.Failure<Func<Data, Data>>()
_ => Parser.FailUpdate<Data>()
}, new Data("", ""));

Parser.Parse(parser, ref reader, default).Should().Be(new Data("foo", "bar"));
@@ -59,10 +87,47 @@ public void DeserializeStartedObject()
{
"foo" => Parser.String.Updater((string foo, Data data) => data with { Foo = foo }),
"bar" => Parser.String.Updater((string bar, Data data) => data.Bar = bar),
_ => Parser.Failure<Func<Data, Data>>()
_ => Parser.FailUpdate<Data>()
}, new Data("", ""));

Parser.Parse(parser, ref reader, default).Should().Be(new Data("foo", "bar"));
}



[Fact]
public void DeserializeBar()
{
var json = @"
{
""type"": ""bar"",
""bar"": {
""bar_value"": 1
}
}";

var bytes = Encoding.UTF8.GetBytes(json);
var reader = new Utf8JsonReader(bytes);
reader.Read();

Parser.Parse(FooParser, ref reader, default).Should().BeEquivalentTo(new Bar { BarValue = 1});
}

[Fact]
public void DeserializeBaz()
{
var json = @"
{
""type"": ""bar"",
""baz"": {
""baz_value"": ""1""
}
}";

var bytes = Encoding.UTF8.GetBytes(json);
var reader = new Utf8JsonReader(bytes);
reader.Read();
Parser.Parse(FooParser, ref reader, default).Should().BeEquivalentTo(new Baz { BazValue = "1"});
}
}
}

0 comments on commit 596fdd8

Please sign in to comment.