Giter Club home page Giter Club logo

serde's Introduction

Serde.NET

Serde.NET is a port of the popular serde.rs Rust serialization/deserialization library to .NET.

For an overview, see Overview.

Start by adding the serde NuGet package:

dotnet add package serde --prerelease

You can now use the [GenerateSerialize] and [GenerateDeserialize] attributes to automatically implement serialization and deserialization for your own types. Don't forget to mark them partial!

using Serde;
using Serde.Json;

string output = JsonSerializer.Serialize(new SampleClass());

// prints: {"X":3,"Y":"sample"}
Console.WriteLine(output);

var deserialized = JsonSerializer.Deserialize<SampleClass>(output);

// prints SampleClass { X = 3, Y = sample }
Console.WriteLine(deserialized);

[GenerateSerialize, GenerateDeserialize]
partial record SampleClass
{
    // automatically includes public properties and fields
    public int X { get; init; } = 3;
    public string Y = "sample";
}

serde's People

Contributors

agocke avatar filipnavara avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

serde's Issues

Road to 1.0

The following things need to be completed before shipping a release version

  • Deserialization
    • Calling constructors
  • Wrappers for tuples
  • Ability to wrap nested types
    • Automatic nested type wrapping
  • Decide on whether or not to use abstract static interface methods while in preview
    • Update: yes, abstract statics are required

Add SerializeBytes method

Should probably have signature

void SerializeBytes(ReadOnlySpan<byte> bytes);

This would be for formats which can have a more efficient byte array representation.

Replace Option<T> type with Remora.Rest's Optional<TResult>

The Optional type from Remora.Rest is a more feature-rich implementation of the same principal, and in my opinion comes with better naming. @Nihlus has given his approval for its use in this library in anticipation of Serde being promoted into a .NET feature.

image

Additional features:

  • IsDefined() and IsDefined(out TValue)
  • Map() methods, allowing the conversion of one optional type into another
  • OrDefault() and OrThrow() methods, though the former does in fact live in the Option type
  • Plenty of additional analyzers through System.Diagnostics, System.Diagnostics.CodeAnalysis, and Jetbrains.Annotations.
  • Equality operators
  • GetHashCode() and ToString()

ImmutableArray<ReferenceType> causes virtual method pointer lookup failure in NativeAOT

Not sure if the issue is with serde-dn or NativeAOT, but I ran into an issue with deserializing ImmutableArray in dnvm after I had switched workload it to a reference type. I found making it a struct again fixed the issue so far, and I thought I'd let you know in case you hit something similar.

Process terminated. Generic virtual method pointer lookup failure.

Declaring type handle: MethodTable:0x00007FF6470BFF80
Target type handle: MethodTable:0x00007FF64711D7E8
Method name: Serde.IDeserializeVisitor<System.Collections.Immutable.ImmutableArray<T>>.VisitEnumerable
Instantiation:
  Argument 00000000: MethodTable:0x00007FF647113320

How to deserialize a subtype using the type name given in the input data?

Hi, I'm currently working on a project where I'm implementing a deserializer using Serde.NET. I have encountered a specific scenario and would appreciate some guidance on how to approach it.

Here is the simplified example of the scenario:

We first declare the following example types:

[GenerateDeserialize]
class Foo {
  public AbstractBar bar;
}

abstract class AbstractBar { }

[GenerateDeserialize]
class Bar1 : AbstractBar {
  public int bar;
}

[GenerateDeserialize]
class Bar2 : AbstractBar {
  public double bar;
}

And then, we extend the JSON encoding so that, if an object starts with a property "_t" (or whatever other type tagging, the details don't matter), the value of the property is the FQN of the type, so we can deserialize children class or interface implementations and assign them to the base class/interface.

For example, the following JSON input:

{ "bar": { "_t": "Bar1", "bar": 1234 } }

Would deserialize to the following data structure.

new Foo { bar = new Bar1 { bar = 1234 } }

I have noticed that there's IDeserializer::DeserializeType(typeName, fieldNames, v), but I can't find any detailed documentation or examples in this repository on how to use it (other than redirecting it into DeserializeDictionary). Could you please provide some guidance on implementing a feature like this in the deserializer?

Deterministic Serialization?

Hey this is a great library!

I was wondering if there are any guarantees around deterministic serialization. Is it possible to annotate properties with an order attribute that will guarantee the serialization order of properties?

F# support

After playing around with the C# implementation, I was thinking about what an F# implementation might look like using Myriad:

C#

[GenerateSerialize]
public partial class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
public partial class Person : Serde.ISerialize
{
    void Serde.ISerialize.Serialize(ISerializer serializer)
    {
        var type = serializer.SerializeType("Person", 2);
        type.SerializeField("Name", new StringWrap(Name));
        type.SerializeField("Age", new Int32Wrap(Age));
        type.End();
    }
}

F#

[<GenerateSerialize>]
type Person = 
    {
        Name: string
        Age : int
    }

Generated:

module Person

let toSerializable (person: Person) =
    { new Serde.ISerialize with
        member this.Serialize(serializer: ISerializer) = 
            let type = serializer.SerializeType("Person", 2)
            type.SerializeField("Name", StringWrap(person.Name))
            type.SerializeField("Age", Int32Wrap(person.Age))
            type.End() 
    }

Usage:

{ Name = "John"; Age = 100 }
|> Person.toSerializable
|> JsonSerializer.Serialize
|> printfn "%s"

It wouldn't be quite as user friendly as the C# generator version because:

  • User would be required to manually include generated output file in the .fsproj file
  • Possible .toml config file needed
  • Myriad NuGet package required

Properties named "Default" causes errors in generated source files

When working on dnvm, I made a property named "Default" that ended up breaking the generated files. Renaming it to another name worked fine. I'm guessing this would cause an issue with any keywords.

Generated file:

partial record Manifest : Serde.IDeserialize<Dnvm.Manifest>
    {
        static Dnvm.Manifest Serde.IDeserialize<Dnvm.Manifest>.Deserialize<D>(ref D deserializer)
        {
            var visitor = new SerdeVisitor();
            var fieldNames = new[]{"Default", "Workloads"};
            return deserializer.DeserializeType<Dnvm.Manifest, SerdeVisitor>("Manifest", fieldNames, visitor);
        }

        private sealed class SerdeVisitor : Serde.IDeserializeVisitor<Dnvm.Manifest>
        {
            public string ExpectedTypeName => "Dnvm.Manifest";
            Dnvm.Manifest Serde.IDeserializeVisitor<Dnvm.Manifest>.VisitDictionary<D>(ref D d)
            {
                Serde.Option < Dnvm.Workload > default = default; // Error
                Serde.Option<System.Collections.Immutable.ImmutableArray<Dnvm.Workload>> workloads = default;
                while (d.TryGetNextKey<string, StringWrap>(out string? key))
                {
                    switch (key)
                    {
                        case "default":
                        default = d.GetNextValue<Dnvm.Workload, Dnvm.Workload>(); // Error
                            break;
                        case "workloads":
                            workloads = d.GetNextValue<System.Collections.Immutable.ImmutableArray<Dnvm.Workload>, ImmutableArrayWrap.DeserializeImpl<Dnvm.Workload, Dnvm.Workload>>();
                            break;
                        default:
                            break;
                    }
                }

                Dnvm.Manifest newType = new Dnvm.Manifest()
                {Default = default.GetValueOrThrow("Default"), Workloads = workloads.GetValueOrThrow("Workloads"), }; // Error
                return newType;
            }
        }
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.