Add code gen package
Add code generation package that automatically generates necessary transformers
C# 9.0 Code generation
With introduction of new code-gen engine, you can opt to have your transformer generated automatically without any imperative code.
//1. use specially provided (via code-gen) Auto.AutoDeconstructable attribute
[Auto.AutoDeconstructable]
//2. provide deconstructable aspect options or leave this attribute out - default options will be engaged
[DeconstructableSettings('_', '∅', '%', '〈', '〉')]
readonly partial /*3. partial modifier is VERY important - you need this cause generated code is placed in different file*/ struct StructPoint3d
{
public double X { get; }
public double Y { get; }
public double Z { get; }
//4. specify constructor and matching deconstructor
public StructPoint3d(double x, double y, double z) { X = x; Y = y; Z = z; }
public void Deconstruct(out double x, out double y, out double z) { x = X; y = Y; z = Z; }
}
//5. sit back, relax and enjoy - code-gen will do the job for you :-)
This in turn might generate the following (parts of code ommited for brevity)
using /* ... */;
[Transformer(typeof(StructPoint3dTransformer))]
readonly partial struct StructPoint3d { }
sealed class StructPoint3dTransformer : TransformerBase<StructPoint3d>
{
private readonly ITransformer<double> _transformer_x = TextTransformer.Default.GetTransformer<double>();
/* specify remaining transformers... */
private const int ARITY = 3;
private readonly TupleHelper _helper = new TupleHelper('_', '∅', '%', '〈', '〉');
protected override StructPoint3d ParseCore(in ReadOnlySpan<char> input)
{
var enumerator = _helper.ParseStart(input, ARITY);
var t1 = _helper.ParseElement(ref enumerator, _transformer_x);
/* parse Y and Z... */
_helper.ParseEnd(ref enumerator, ARITY);
return new StructPoint3d(t1, t2, t3);
}
public override string Format(StructPoint3d element)
{
Span<char> initialBuffer = stackalloc char[32];
var accumulator = new ValueSequenceBuilder<char>(initialBuffer);
try
{
_helper.StartFormat(ref accumulator);
var (x, y, z) = element;
_helper.FormatElement(_transformer_x, x, ref accumulator);
/* format Y and Z... */
_helper.EndFormat(ref accumulator);
return accumulator.AsSpan().ToString();
}
finally { accumulator.Dispose(); }
}
}
Code gen diagnositcs
Various diagnositcs exist to guide end user in creation of proper types that can be consumed by automatic generation. They might for example:
- check if types decorated with Auto* attributes are declared partial (prerequisite for additive code generation)
- validate settings passed via declarative syntax
- validate internal structure of type (i.e. check if constructor has matching Deconstruct method)
- check if external dependencies are included