{"id":19971146,"url":"https://github.com/eiriktsarpalis/PolyType","last_synced_at":"2025-05-04T01:30:45.604Z","repository":{"id":143469695,"uuid":"510064963","full_name":"eiriktsarpalis/PolyType","owner":"eiriktsarpalis","description":"Practical generic programming for .NET","archived":false,"fork":false,"pushed_at":"2025-04-21T08:32:07.000Z","size":1603,"stargazers_count":202,"open_issues_count":28,"forks_count":11,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-28T10:10:07.588Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://eiriktsarpalis.github.io/PolyType/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eiriktsarpalis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-07-03T15:41:08.000Z","updated_at":"2025-04-21T06:48:04.000Z","dependencies_parsed_at":"2024-02-07T11:53:11.375Z","dependency_job_id":"4d891c04-c54a-42a3-8f0a-16e65ec1aba2","html_url":"https://github.com/eiriktsarpalis/PolyType","commit_stats":{"total_commits":286,"total_committers":7,"mean_commits":"40.857142857142854","dds":"0.045454545454545414","last_synced_commit":"fa1a51a1e5da33ab4a023b1fec406d6b85460163"},"previous_names":["eiriktsarpalis/polytype","eiriktsarpalis/typeshape-csharp"],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eiriktsarpalis%2FPolyType","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eiriktsarpalis%2FPolyType/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eiriktsarpalis%2FPolyType/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eiriktsarpalis%2FPolyType/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eiriktsarpalis","download_url":"https://codeload.github.com/eiriktsarpalis/PolyType/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252276955,"owners_count":21722447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T03:01:34.129Z","updated_at":"2025-05-04T01:30:45.586Z","avatar_url":"https://github.com/eiriktsarpalis.png","language":"C#","funding_links":[],"categories":["Content"],"sub_categories":["167. [polytype](https://ignatandrei.github.io/RSCG_Examples/v2/docs/polytype) , in the [FunctionalProgramming](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#functionalprogramming) category"],"readme":"# PolyType [![Build \u0026 Tests](https://github.com/eiriktsarpalis/PolyType/actions/workflows/build.yml/badge.svg)](https://github.com/eiriktsarpalis/PolyType/actions/workflows/build.yml) [![NuGet Badge](https://img.shields.io/nuget/dt/PolyType)](https://www.nuget.org/packages/PolyType/) [![codecov](https://codecov.io/gh/eiriktsarpalis/PolyType/graph/badge.svg?token=1K2FV94SEL)](https://codecov.io/gh/eiriktsarpalis/PolyType)\n\nPolyType is a practical generic programming library for .NET. It facilitates the rapid development of feature-complete, high-performance libraries that interact with user-defined types. This includes serializers, structured loggers, mappers, validators, parsers, random generators, and equality comparers. Its built-in source generator ensures that any library built on top of PolyType gets [Native AOT support for free](https://eiriktsarpalis.wordpress.com/2024/10/22/source-generators-for-free/).\n\nThe project is a port of the [TypeShape](https://github.com/eiriktsarpalis/TypeShape) library for F#, adapted to patterns and idioms available in C#. The name PolyType is a reference to [polytypic programming](https://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Polytypism), another term for generic programming.\n\nSee the [project website](https://eiriktsarpalis.github.io/PolyType) for additional background and [API documentation](https://eiriktsarpalis.github.io/PolyType/api/PolyType.html).\n\n## Quick Start\n\nYou can try the library by installing the `PolyType` NuGet package:\n\n```bash\n$ dotnet add package PolyType\n```\n\nwhich includes the core types and source generator for generating type shapes:\n\n```C#\nusing PolyType;\n\n[GenerateShape]\npublic partial record Person(string name, int age);\n```\n\nDoing this will augment `Person` with an implementation of the `IShapeable\u003cPerson\u003e` interface. This suffices to make `Person` usable with any library that targets the PolyType core abstractions. You can try this out by installing the built-in example libraries:\n\n```bash\n$ dotnet add package PolyType.Examples\n```\n\nHere's how the same value can be serialized to three separate formats.\n\n```csharp\nusing PolyType.Examples.JsonSerializer;\nusing PolyType.Examples.CborSerializer;\nusing PolyType.Examples.XmlSerializer;\n\nPerson person = new(\"Pete\", 70);\nJsonSerializerTS.Serialize(person); // {\"Name\":\"Pete\",\"Age\":70}\nXmlSerializer.Serialize(person);    // \u003cvalue\u003e\u003cName\u003ePete\u003c/Name\u003e\u003cAge\u003e70\u003c/Age\u003e\u003c/value\u003e\nCborSerializer.EncodeToHex(person); // A2644E616D656450657465634167651846\n```\n\nSince the application uses a source generator to produce the shape for `Person`, it is fully compatible with Native AOT. See the [shape providers](https://eiriktsarpalis.github.io/PolyType/shape-providers.html) article for more details on how to use the library with your types.\n\n## Authoring PolyType Libraries\n\nAs a library author, PolyType makes it easy to write high-performance, feature-complete components by targeting its [core abstractions](https://eiriktsarpalis.github.io/PolyType/core-abstractions.html). For example, a parser API using PolyType might look as follows:\n\n```C#\npublic static class MyFancyParser\n{\n    public static T? Parse\u003cT\u003e(string myFancyFormat) where T : IShapeable\u003cT\u003e;\n}\n```\n\nThe [`IShapeable\u003cT\u003e` constraint](https://eiriktsarpalis.github.io/PolyType/api/PolyType.IShapeable-1.html) indicates that the parser only works with types augmented with PolyType metadata. This metadata can be provided using the PolyType source generator:\n\n```C#\nPerson? person = MyFancyParser.Parse\u003cPerson\u003e(format); // Compiles\n\n[GenerateShape] // Generate an IShapeable\u003cTPerson\u003e implementation\npartial record Person(string name, int age, List\u003cPerson\u003e children);\n```\n\nFor more information see:\n\n* The [core abstractions](https://eiriktsarpalis.github.io/PolyType/core-abstractions.html) document for an overview of the core programming model.\n* The [shape providers](https://eiriktsarpalis.github.io/PolyType/shape-providers.html) document for an overview of the built-in shape providers and their APIs.\n* The generated [API documentation](https://eiriktsarpalis.github.io/PolyType/api/PolyType.html) for the project.\n* The [`PolyType.Examples`](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType.Examples) project for advanced examples of libraries built on top of PolyType.\n\n## Case Study: Writing a JSON serializer\n\nThe repo includes a [JSON serializer](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType.Examples/JsonSerializer) built on top of the `Utf8JsonWriter`/`Utf8JsonReader` primitives provided by System.Text.Json. At the time of writing, the full implementation is just under 1200 lines of code but exceeds STJ's built-in `JsonSerializer` both in terms of [supported types](https://github.com/eiriktsarpalis/PolyType/blob/main/tests/PolyType.Tests/JsonTests.cs) and performance.\n\n### Performance\n\nHere's a [benchmark](https://github.com/eiriktsarpalis/PolyType/blob/main/tests/PolyType.Benchmarks/JsonBenchmark.cs) comparing `System.Text.Json` with the included PolyType implementation:\n\n#### Serialization\n\n| Method                          | Mean      | Ratio | Allocated | Alloc Ratio |\n|-------------------------------- |----------:|------:|----------:|------------:|\n| Serialize_StjReflection         | 150.43 ns |  1.00 |     312 B |        1.00 |\n| Serialize_StjSourceGen          | 151.31 ns |  1.01 |     312 B |        1.00 |\n| Serialize_StjSourceGen_FastPath |  96.79 ns |  0.64 |         - |        0.00 |\n| Serialize_PolyTypeReflection    | 113.19 ns |  0.75 |         - |        0.00 |\n| Serialize_PolyTypeSourceGen     | 112.92 ns |  0.75 |         - |        0.00 |\n\n#### Deserialization\n\n| Method                         | Mean     | Ratio | Allocated | Alloc Ratio |\n|------------------------------- |---------:|------:|----------:|------------:|\n| Deserialize_StjReflection      | 534.0 ns |  1.00 |    1016 B |        1.00 |\n| Deserialize_StjSourceGen       | 534.6 ns |  1.00 |     992 B |        0.98 |\n| Deserialize_PolyTypeReflection | 273.1 ns |  0.51 |     440 B |        0.43 |\n| Deserialize_PolyTypeSourceGen  | 266.3 ns |  0.50 |     440 B |        0.43 |\n\nEven though both serializers target the same underlying reader and writer types, the PolyType implementation is ~75% faster for serialization and ~100% faster for deserialization, when compared with System.Text.Json's metadata serializer. As expected, fast-path serialization is still fastest since its implementation is fully inlined.\n\n## Known libraries based on PolyType\n\nThe following code bases are based upon PolyType and may be worth checking out.\n\n* [Nerdbank.MessagePack](https://github.com/AArnott/Nerdbank.MessagePack) - a MessagePack library with performance to rival MessagePack-CSharp, and greater simplicity and additional features.\n\n## Project structure\n\nThe repo consists of the following projects:\n\n* The core `PolyType` library containing:\n  * The [core abstractions](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType/Abstractions) defining the type model.\n  * The [reflection provider](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType/ReflectionProvider) implementation.\n  * The [model classes](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType/SourceGenModel) used by the source generator.\n* The [`PolyType.SourceGenerator`](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType.SourceGenerator) project contains the built-in source generator implementation.\n* The [`PolyType.Roslyn`](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType.Roslyn) library exposes a set of components for extracting data models from Roslyn type symbols. Used as the foundation for the built-in source generator.\n* [`PolyType.Examples`](https://github.com/eiriktsarpalis/PolyType/tree/main/src/PolyType.Examples) containing library examples:\n  * A serializer built on top of System.Text.Json,\n  * A serializer built on top of System.Xml,\n  * A serializer built on top of System.Formats.Cbor,\n  * A `ConfigurationBinder` like implementation,\n  * A dependency injection implementation,\n  * A simple pretty-printer for .NET values,\n  * A generic random value generator based on `System.Random`,\n  * A JSON schema generator for .NET types,\n  * An object cloning function,\n  * A structural `IEqualityComparer\u003cT\u003e` generator for POCOs and collections,\n  * An object validator in the style of System.ComponentModel.DataAnnotations.\n  * A simple .NET object mapper.\n* The [`applications`](https://github.com/eiriktsarpalis/PolyType/tree/main/applications) folder contains sample Native AOT console applications.\n\n## CI Packages\n\nCI builds of NuGet packages are available on [feedz.io](https://feedz.io/). To use the feed, add the following package source to your `NuGet.config`:\n\n```xml\n\u003cconfiguration\u003e\n  \u003cpackageSources\u003e\n    \u003cadd key=\"feedz.io\" value=\"https://f.feedz.io/eiriktsarpalis/PolyType/nuget/index.json\" /\u003e\n  \u003c/packageSources\u003e\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feiriktsarpalis%2FPolyType","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feiriktsarpalis%2FPolyType","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feiriktsarpalis%2FPolyType/lists"}