-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
task: readded support for the IDecimal primitive type.
- Loading branch information
Showing
27 changed files
with
1,008 additions
and
245 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
namespace Primitively; | ||
|
||
/// <summary> | ||
/// This attribute should be used on a <c>partial record struct</c> to source generate | ||
/// a Primitively <see cref="IDecimal"/> type that encapsulates a <see cref="decimal"/> value. | ||
/// </summary> | ||
/// <example> | ||
/// These examples show how to use the Decimal attribute to source generate a Primitively <see cref="IDecimal"/> type. | ||
/// <code> | ||
/// [Decimal] | ||
/// public partial record struct Example; | ||
/// </code> | ||
/// <code> | ||
/// [Decimal(3)] | ||
/// public partial record struct Example; | ||
/// </code> | ||
/// </example> | ||
[AttributeUsage(AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] | ||
public sealed class DecimalAttribute : NumericAttribute | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DecimalAttribute"/> class. | ||
/// </summary> | ||
public DecimalAttribute() | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DecimalAttribute"/> class with the specified number of fractional digits. | ||
/// </summary> | ||
/// <param name="digits">The number of fractional digits in the value of the source generated Primitively <see cref="IDecimal"/> type.</param> | ||
public DecimalAttribute(int digits) | ||
{ | ||
Digits = digits; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DecimalAttribute"/> class with the specified number of fractional digits and rounding mode. | ||
/// </summary> | ||
/// <param name="digits">The number of fractional digits in the value of the source generated Primitively <see cref="IDecimal"/> type.</param> | ||
/// <param name="mode">The rounding specification for how to round value of the source generated Primitively <see cref="IDecimal"/> type if it is midway between two other numbers.</param> | ||
public DecimalAttribute(int digits, MidpointRounding mode) | ||
{ | ||
Digits = digits; | ||
Mode = mode; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the number of fractional digits in the value of the source generated Primitively <see cref="IDecimal"/> type. | ||
/// </summary> | ||
/// <remarks> | ||
/// Valid values are: -1 to 28. | ||
/// Values above 28 will default to: -1. | ||
/// Values below -1 will default to: -1. | ||
/// A value of -1 will result in: no rounding. | ||
/// </remarks> | ||
public int Digits { get; } | ||
|
||
/// <summary> | ||
/// Gets the rounding specification for how to round value of the source generated Primitively <see cref="IDecimal"/> type | ||
/// if it is midway between two other numbers. | ||
/// </summary> | ||
/// <remarks> | ||
/// If the value of <see cref="Digits"/> is -1, this property will have no effect. | ||
/// </remarks> | ||
public MidpointRounding Mode { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
namespace Primitively; | ||
|
||
/// <summary> | ||
/// This class represents metadata properties common to all source generated Primitively numeric types. | ||
/// </summary> | ||
/// <param name="Type">The .NET type of the Primitively type.</param> | ||
/// <param name="Example">An optional example of the integer.</param> | ||
/// <param name="CreateFrom">A function that creates an instance of the Primitively type from a string.</param> | ||
/// <param name="Minimum">The minimum value that can be set on the source generated Primitively type.</param> | ||
/// <param name="Maximum">The maximum value that can be set on the source generated Primitively type.</param> | ||
/// <param name="Digits">The number of fractional digits in the value on the source generated Primitively type</param> | ||
/// <param name="Mode">The rounding specification for how to round value of the source generated Primitively type | ||
/// if it is midway between two other numbers.</param> | ||
public sealed record DecimalInfo( | ||
Type Type, | ||
string? Example, | ||
Func<string?, IPrimitive> CreateFrom, | ||
decimal Minimum, | ||
decimal Maximum, | ||
int Digits, | ||
MidpointRounding Mode) | ||
: NumericInfo<decimal>(DataType.Decimal, Type, Example, CreateFrom, Minimum, Maximum); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace Primitively; | ||
|
||
/// <summary> | ||
/// Defines a contract for a Primitively type that encapsulates a <see cref="decimal"/> value. | ||
/// </summary> | ||
/// <remarks> | ||
/// Implementations of this interface are source generated by Primitively and inherit from both <see cref="IPrimitive{T}"/> and <see cref="INumeric"/> interfaces. | ||
/// </remarks> | ||
public interface IDecimal : IPrimitive<decimal>, INumeric | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
src/Primitively.MongoDB.Bson/Serialization/Serializers/BsonIDecimalSerializer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
using MongoDB.Bson; | ||
using MongoDB.Bson.Serialization; | ||
using MongoDB.Bson.Serialization.Options; | ||
using MongoDB.Bson.Serialization.Serializers; | ||
|
||
namespace Primitively.MongoDB.Bson.Serialization.Serializers; | ||
|
||
/// <summary> | ||
/// Represents a BSON serializer for Primitively <see cref="IDecimal"/> types that encapsulate <see cref="decimal"/> values. | ||
/// </summary> | ||
public class BsonIDecimalSerializer<TPrimitive> : | ||
StructSerializerBase<TPrimitive>, | ||
IRepresentationConfigurable<BsonIDecimalSerializer<TPrimitive>>, | ||
IRepresentationConverterConfigurable<BsonIDecimalSerializer<TPrimitive>> where TPrimitive : struct, IDecimal | ||
{ | ||
private readonly DecimalSerializer _serializer; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
/// <remarks> | ||
/// The default representation is <see cref="BsonType.String"/>. | ||
/// </remarks> | ||
public BsonIDecimalSerializer() | ||
{ | ||
_serializer = new DecimalSerializer(); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
/// <param name="representation">The representation.</param> | ||
public BsonIDecimalSerializer(BsonType representation) | ||
{ | ||
_serializer = new DecimalSerializer(representation); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
/// <param name="representation">The representation.</param> | ||
/// <param name="converter">The converter.</param> | ||
public BsonIDecimalSerializer(BsonType representation, RepresentationConverter converter) | ||
{ | ||
_serializer = new DecimalSerializer(representation, converter); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
/// <param name="serializer">The serializer.</param> | ||
private BsonIDecimalSerializer(DecimalSerializer serializer) | ||
{ | ||
_serializer = serializer; | ||
} | ||
/// <summary> | ||
/// Gets a cached instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
public static BsonIDecimalSerializer<TPrimitive> Instance { get; } = new(); | ||
|
||
/// <summary> | ||
/// Gets the converter. | ||
/// </summary> | ||
public RepresentationConverter Converter => _serializer.Converter; | ||
|
||
/// <summary> | ||
/// Gets the representation. | ||
/// </summary> | ||
public BsonType Representation => _serializer.Representation; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BsonIDecimalSerializer{TPrimitive}"/> class. | ||
/// </summary> | ||
/// <param name="serializer">The serializer.</param> | ||
public static BsonIDecimalSerializer<TPrimitive> Create(DecimalSerializer serializer) => new(serializer); | ||
|
||
/// <summary> | ||
/// Deserializes a value. | ||
/// </summary> | ||
/// <param name="context">The deserialization context.</param> | ||
/// <param name="args">The deserialization args.</param> | ||
/// <returns>A deserialized value.</returns> | ||
public override TPrimitive Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) | ||
{ | ||
var value = _serializer.Deserialize(context, args); | ||
|
||
return (TPrimitive)Activator.CreateInstance(typeof(TPrimitive), value)!; | ||
} | ||
|
||
/// <summary> | ||
/// Serializes a value. | ||
/// </summary> | ||
/// <param name="context">The serialization context.</param> | ||
/// <param name="args">The serialization args.</param> | ||
/// <param name="value">The object.</param> | ||
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TPrimitive value) | ||
{ | ||
_serializer.Serialize(context, args, value.Value); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a serializer that has been reconfigured with the specified item serializer. | ||
/// </summary> | ||
/// <param name="converter">The converter.</param> | ||
/// <returns>The reconfigured serializer.</returns> | ||
public BsonIDecimalSerializer<TPrimitive> WithConverter(RepresentationConverter converter) | ||
{ | ||
if (converter == _serializer.Converter) | ||
{ | ||
return this; | ||
} | ||
|
||
return new BsonIDecimalSerializer<TPrimitive>(_serializer.Representation, converter); | ||
} | ||
|
||
// Explicit interface implementations | ||
IBsonSerializer IRepresentationConverterConfigurable.WithConverter(RepresentationConverter converter) | ||
{ | ||
return WithConverter(converter); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a serializer that has been reconfigured with the specified representation. | ||
/// </summary> | ||
/// <param name="representation">The representation.</param> | ||
/// <returns>The reconfigured serializer.</returns> | ||
public BsonIDecimalSerializer<TPrimitive> WithRepresentation(BsonType representation) | ||
{ | ||
if (representation == _serializer.Representation) | ||
{ | ||
return this; | ||
} | ||
|
||
return new BsonIDecimalSerializer<TPrimitive>(representation, _serializer.Converter); | ||
} | ||
IBsonSerializer IRepresentationConfigurable.WithRepresentation(BsonType representation) | ||
{ | ||
return WithRepresentation(representation); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/Primitively.MongoDB.Bson/Serialization/Serializers/BsonIDecimalSerializerOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using MongoDB.Bson; | ||
using MongoDB.Bson.Serialization; | ||
using MongoDB.Bson.Serialization.Options; | ||
|
||
namespace Primitively.MongoDB.Bson.Serialization.Serializers; | ||
|
||
/// <summary> | ||
/// Represents the options used to configure the BSON serialization of Primitively <see cref="IDecimal"/> types. | ||
/// </summary> | ||
public class BsonIDecimalSerializerOptions : IBsonConvertibleSerializerOptions<BsonIDecimalSerializerOptions> | ||
{ | ||
/// <summary> | ||
/// Gets the <see cref="Primitively.DataType"/> of the Primitively <see cref="IDecimal"/> type. | ||
/// </summary> | ||
/// <value><see cref="DataType.Decimal"/></value> | ||
public DataType DataType { get; } = DataType.Decimal; | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="BsonType"/> used to represent the Primitively <see cref="IDecimal"/> type. | ||
/// </summary> | ||
/// <value><see cref="BsonType.Decimal128"/></value> | ||
public BsonType Representation { get; set; } = BsonType.Decimal128; | ||
|
||
/// <summary> | ||
/// Gets or sets the type used to serialize Primitively <see cref="IDecimal"/> types. | ||
/// </summary> | ||
/// <value><![CDATA[typeof(BsonIDecimalSerializer<>)]]></value> | ||
public Type SerializerType { get; set; } = typeof(BsonIDecimalSerializer<>); | ||
|
||
/// <summary> | ||
/// Gets or sets whether to allow overflow. | ||
/// </summary> | ||
public bool AllowOverflow { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets whether to allow truncation. | ||
/// </summary> | ||
public bool AllowTruncation { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the function used to create an instance of the type used to serialize Primitively <see cref="IDecimal"/> types. | ||
/// </summary> | ||
public Func<BsonIDecimalSerializerOptions, Type, IBsonSerializer> CreateInstance { get; set; } = (options, primitiveType) => | ||
{ | ||
// Construct a Bson serializer for the given Primitively type using the options | ||
var serializerType = options.GetSerializerType(primitiveType); | ||
// Create an instance of the serializer | ||
var serializerInstance = (IBsonSerializer)Activator.CreateInstance( | ||
serializerType, | ||
options.Representation, | ||
new RepresentationConverter(options.AllowOverflow, options.AllowTruncation))!; | ||
return serializerInstance; | ||
}; | ||
|
||
Func<Type, IBsonSerializer> IBsonSerializerOptions.CreateInstance => (primitiveType) => CreateInstance.Invoke(this, primitiveType); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/Primitively/EmbeddedResources/Numeric/FloatingPoint/DecimalPreMatchCheckMethod.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
| ||
private static void PreMatchCheck(ref global::PRIMITIVE_VALUE_TYPE value) | ||
{ | ||
if (Digits >= 0) | ||
{ | ||
value = global::System.Math.Round(value, Digits, Mode); | ||
} | ||
} |
Oops, something went wrong.