RSCG – UnitGenerator
RSCG – UnitGenerator
name | UnitGenerator |
nuget | https://www.nuget.org/packages/UnitGenerator/ |
link | https://github.com/Cysharp/UnitGenerator |
author | Cysharp, Inc |
Generating classes instead of value objects( e.g. int)
This is how you can use UnitGenerator .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath> </PropertyGroup> <ItemGroup> <PackageReference Include="UnitGenerator" Version="1.5.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> </Project>
The code that you will use is
// See https://aka.ms/new-console-template for more information using StronglyDemo; Person p = new(); //p.SetBirthDate(1970, 4, 16); p.SetBirthDate(new YearId(1970) , new MonthId(4),new DayId( 16)); Console.WriteLine(p.BirthDate);
using UnitGenerator; namespace StronglyDemo; [UnitOf(typeof(int))] public partial struct YearId { } [UnitOf(typeof(int))] public partial struct MonthId { } [UnitOf(typeof(int))] public partial struct DayId { } internal class Person { public DateTime BirthDate { get; internal set; } public void SetBirthDate(YearId yearId,MonthId monthId,DayId dayId) { BirthDate = new DateTime(yearId.AsPrimitive(), monthId.AsPrimitive(), dayId.AsPrimitive()); } }
The code that is generated is
// <auto-generated> // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // </auto-generated> #pragma warning disable CS8669 using System; using System.Globalization; #if NET7_0_OR_GREATER using System.Numerics; #endif namespace StronglyDemo { [System.ComponentModel.TypeConverter(typeof(DayIdTypeConverter))] readonly partial struct DayId : IEquatable<DayId> #if NET7_0_OR_GREATER , IEqualityOperators<DayId, DayId, bool> #endif { readonly int value; public int AsPrimitive() => value; public DayId(int value) { this.value = value; } public static explicit operator int(DayId value) { return value.value; } public static explicit operator DayId(int value) { return new DayId(value); } public bool Equals(DayId other) { return value.Equals(other.value); } public override bool Equals(object obj) { if (obj == null) return false; var t = obj.GetType(); if (t == typeof(DayId)) { return Equals((DayId)obj); } if (t == typeof(int)) { return value.Equals((int)obj); } return value.Equals(obj); } public static bool operator ==(DayId x, DayId y) { return x.value.Equals(y.value); } public static bool operator !=(DayId x, DayId y) { return !x.value.Equals(y.value); } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() => value.ToString(); // Default private class DayIdTypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof(DayId); private static readonly Type ValueType = typeof(int); public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) { if (sourceType == WrapperType || sourceType == ValueType) { return true; } return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType) { if (destinationType == WrapperType || destinationType == ValueType) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value != null) { var t = value.GetType(); if (t == typeof(DayId)) { return (DayId)value; } if (t == typeof(int)) { return new DayId((int)value); } } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is DayId wrappedValue) { if (destinationType == WrapperType) { return wrappedValue; } if (destinationType == ValueType) { return wrappedValue.AsPrimitive(); } } return base.ConvertTo(context, culture, value, destinationType); } } } }
// <auto-generated> // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // </auto-generated> #pragma warning disable CS8669 using System; using System.Globalization; #if NET7_0_OR_GREATER using System.Numerics; #endif namespace StronglyDemo { [System.ComponentModel.TypeConverter(typeof(MonthIdTypeConverter))] readonly partial struct MonthId : IEquatable<MonthId> #if NET7_0_OR_GREATER , IEqualityOperators<MonthId, MonthId, bool> #endif { readonly int value; public int AsPrimitive() => value; public MonthId(int value) { this.value = value; } public static explicit operator int(MonthId value) { return value.value; } public static explicit operator MonthId(int value) { return new MonthId(value); } public bool Equals(MonthId other) { return value.Equals(other.value); } public override bool Equals(object obj) { if (obj == null) return false; var t = obj.GetType(); if (t == typeof(MonthId)) { return Equals((MonthId)obj); } if (t == typeof(int)) { return value.Equals((int)obj); } return value.Equals(obj); } public static bool operator ==(MonthId x, MonthId y) { return x.value.Equals(y.value); } public static bool operator !=(MonthId x, MonthId y) { return !x.value.Equals(y.value); } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() => value.ToString(); // Default private class MonthIdTypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof(MonthId); private static readonly Type ValueType = typeof(int); public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) { if (sourceType == WrapperType || sourceType == ValueType) { return true; } return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType) { if (destinationType == WrapperType || destinationType == ValueType) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value != null) { var t = value.GetType(); if (t == typeof(MonthId)) { return (MonthId)value; } if (t == typeof(int)) { return new MonthId((int)value); } } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is MonthId wrappedValue) { if (destinationType == WrapperType) { return wrappedValue; } if (destinationType == ValueType) { return wrappedValue.AsPrimitive(); } } return base.ConvertTo(context, culture, value, destinationType); } } } }
// <auto-generated> // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // </auto-generated> #pragma warning disable CS8669 using System; using System.Globalization; #if NET7_0_OR_GREATER using System.Numerics; #endif namespace StronglyDemo { [System.ComponentModel.TypeConverter(typeof(YearIdTypeConverter))] readonly partial struct YearId : IEquatable<YearId> #if NET7_0_OR_GREATER , IEqualityOperators<YearId, YearId, bool> #endif { readonly int value; public int AsPrimitive() => value; public YearId(int value) { this.value = value; } public static explicit operator int(YearId value) { return value.value; } public static explicit operator YearId(int value) { return new YearId(value); } public bool Equals(YearId other) { return value.Equals(other.value); } public override bool Equals(object obj) { if (obj == null) return false; var t = obj.GetType(); if (t == typeof(YearId)) { return Equals((YearId)obj); } if (t == typeof(int)) { return value.Equals((int)obj); } return value.Equals(obj); } public static bool operator ==(YearId x, YearId y) { return x.value.Equals(y.value); } public static bool operator !=(YearId x, YearId y) { return !x.value.Equals(y.value); } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() => value.ToString(); // Default private class YearIdTypeConverter : System.ComponentModel.TypeConverter { private static readonly Type WrapperType = typeof(YearId); private static readonly Type ValueType = typeof(int); public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) { if (sourceType == WrapperType || sourceType == ValueType) { return true; } return base.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType) { if (destinationType == WrapperType || destinationType == ValueType) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { if (value != null) { var t = value.GetType(); if (t == typeof(YearId)) { return (YearId)value; } if (t == typeof(int)) { return new YearId((int)value); } } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is YearId wrappedValue) { if (destinationType == WrapperType) { return wrappedValue; } if (destinationType == ValueType) { return wrappedValue.AsPrimitive(); } } return base.ConvertTo(context, culture, value, destinationType); } } } }
// <auto-generated> // THIS (.cs) FILE IS GENERATED BY UnitGenerator. DO NOT CHANGE IT. // </auto-generated> #pragma warning disable CS8669 #pragma warning disable CS8625 using System; #if NET7_0_OR_GREATER using System.Numerics; #endif namespace UnitGenerator { [AttributeUsage(AttributeTargets.Struct, AllowMultiple = false)] internal class UnitOfAttribute : Attribute { public Type Type { get; } public UnitGenerateOptions Options { get; } public UnitArithmeticOperators ArithmeticOperators { get; set; } = UnitArithmeticOperators.All; public string ToStringFormat { get; set; } public UnitOfAttribute(Type type, UnitGenerateOptions options = UnitGenerateOptions.None) { this.Type = type; this.Options = options; } } [Flags] internal enum UnitGenerateOptions { None = 0, ImplicitOperator = 1, ParseMethod = 1 << 1, MinMaxMethod = 1 << 2, ArithmeticOperator = 1 << 3, ValueArithmeticOperator = 1 << 4, Comparable = 1 << 5, Validate = 1 << 6, JsonConverter = 1 << 7, MessagePackFormatter = 1 << 8, DapperTypeHandler = 1 << 9, EntityFrameworkValueConverter = 1 << 10, WithoutComparisonOperator = 1 << 11, JsonConverterDictionaryKeySupport = 1 << 12, Normalize = 1 << 13, } [Flags] internal enum UnitArithmeticOperators { All = Addition | Subtraction | Multiply | Division | Increment | Decrement, Addition = 1, Subtraction = 1 << 1, Multiply = 1 << 2, Division = 1 << 3, Increment = 1 << 4, Decrement = 1 << 5, } }
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/UnitGenerator
Leave a Reply