Skip to content

Commit

Permalink
Improve triple-slash documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveDunn committed Nov 1, 2024
1 parent 838ba80 commit 9f3981b
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 14 deletions.
63 changes: 62 additions & 1 deletion src/Vogen.SharedTypes/ValueObjectAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@ public class ValueObjectAttribute<T> : ValueObjectAttribute
// keep this signature in-line with `VogenConfiguration`
// as the syntax/semantics are read in the generator
// using parameter indexes (i.e. it expected param 0 to be the underlying type etc.
/// <summary>
/// Configures aspects of this individual value object.
/// </summary>
/// <param name="conversions">Specifies what conversion code is generated - defaults to <see cref="Conversions.Default"/> which generates type converters and a converter to handle serialization using System.Text.Json</param>
/// <param name="throws">Specifies the type of exception thrown when validation fails—defaults to <see cref="ValueObjectValidationException"/>.</param>
/// <param name="customizations">Simple customization switches—defaults to <see cref="Customizations.None"/>.</param>
/// <param name="deserializationStrictness">Specifies how strict deserialization is, e.g. should your Validate method be called, or should pre-defined instances that otherwise invalid be allowed - defaults to <see cref="DeserializationStrictness.AllowValidAndKnownInstances"/>.</param>
/// <param name="debuggerAttributes">Specifies the level that debug attributes are written as some IDEs don't support all of them, e.g., Rider - defaults to <see cref="DebuggerAttributeGeneration.Full"/> which generates DebuggerDisplay and a debugger proxy type for IDEs that support them</param>
/// <param name="comparison">Species which comparison code is generated—defaults to <see cref="ComparisonGeneration.UseUnderlying"/> which hoists any IComparable implementations from the primitive.</param>
/// <param name="stringComparers">Specifies which string comparison code is generated—defaults to <see cref="StringComparersGeneration.Omit"/> which doesn't generate anything related to string comparison.</param>
/// <param name="toPrimitiveCasting">Controls how cast operators are generated for casting from the Value Object to the primitive.
/// Options are implicit or explicit or none. Explicit is preferred over implicit if you really need them, but isn't recommended.
/// See <see href="https://github.com/SteveDunn/Vogen/wiki/Casting"/> for more information.</param>
/// <param name="fromPrimitiveCasting">Controls how cast operators are generated for casting from the primitive to the Value Object.
/// Options are implicit or explicit or none. Explicit is preferred over implicit if you really need them, but isn't recommended.
/// See &lt;see href="https://github.com/SteveDunn/Vogen/wiki/Casting"/&gt; for more information.</param>
/// <param name="parsableForStrings">Specifies what is generated for IParsable types for strings - defaults to <see cref="ParsableForStrings.GenerateMethodsAndInterface"/>.</param>
/// <param name="parsableForPrimitives">Specifies what is generated for Parse and TryParse methods - defaults to <see cref="ParsableForPrimitives.HoistMethodsAndInterfaces"/>.</param>
/// <param name="tryFromGeneration">Specifies what to write for TryFrom methods—defaults to <see cref="TryFromGeneration.GenerateBoolAndErrorOrMethods"/>.</param>
/// <param name="isInitializedMethodGeneration">Specifies whether to generate an IsInitialized() method - defaults to <see cref="IsInitializedMethodGeneration.Generate"/>.</param>
/// <param name="primitiveEqualityGeneration">
/// Specifies whether to generate primitive comparison operators, allowing this type to be compared for equality to the primitive.
/// Defaults to <see cref="PrimitiveEqualityGeneration.GenerateOperatorsAndMethods"/>
/// <example>
/// <para>
/// var vo = MyInt.From(123);
/// </para>
/// <para>
/// bool same = vo == 123;
/// </para>
/// </example>
/// </param>
public ValueObjectAttribute(
Conversions conversions = Conversions.Default,
Type? throws = null!,
Expand Down Expand Up @@ -51,7 +83,7 @@ public ValueObjectAttribute(
}

/// <summary>
/// Marks a type as a Value Object. The type that this is applied to should be partial so that the
/// MMMarks a type as a Value Object. The type that this is applied to should be partial so that the
/// source generator can augment it with equality, creation barriers, and any conversions.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)]
Expand All @@ -61,6 +93,35 @@ public class ValueObjectAttribute : Attribute
// as the syntax/semantics are read in the generator
// using parameter indexes (i.e. it expected param 0 to be the underlying type etc).
// ReSharper disable once MemberCanBeProtected.Global
/// <summary>
/// Configures aspects of this individual value object.
/// </summary>
/// <param name="underlyingType">The type of the primitive that is being wrapped—defaults to int.</param>
/// <param name="conversions">Specifies what conversion code is generated - defaults to <see cref="Conversions.Default"/> which generates type converters and a converter to handle serialization using System.Text.Json</param>
/// <param name="throws">Specifies the type of exception thrown when validation fails—defaults to <see cref="ValueObjectValidationException"/>.</param>
/// <param name="customizations">Simple customization switches—defaults to <see cref="Customizations.None"/>.</param>
/// <param name="deserializationStrictness">Specifies how strict deserialization is, e.g. should your Validate method be called, or should pre-defined instances that otherwise invalid be allowed - defaults to <see cref="DeserializationStrictness.AllowValidAndKnownInstances"/>.</param>
/// <param name="debuggerAttributes">Specifies the level that debug attributes are written as some IDEs don't support all of them, e.g., Rider - defaults to <see cref="DebuggerAttributeGeneration.Full"/> which generates DebuggerDisplay and a debugger proxy type for IDEs that support them</param>
/// <param name="comparison">Species which comparison code is generated—defaults to <see cref="ComparisonGeneration.UseUnderlying"/> which hoists any IComparable implementations from the primitive.</param>
/// <param name="stringComparers">Specifies which string comparison code is generated—defaults to <see cref="StringComparersGeneration.Omit"/> which doesn't generate anything related to string comparison.</param>
/// <param name="toPrimitiveCasting">Specifies the type of casting from wrapper to primitive - defaults to <see cref="CastOperator.Explicit"/>.</param>
/// <param name="fromPrimitiveCasting">Specifies the type of casting from primitive to wrapper - default to <see cref="CastOperator.Explicit"/>.</param>
/// <param name="parsableForStrings">Specifies what is generated for IParsable types for strings - defaults to <see cref="ParsableForStrings.GenerateMethodsAndInterface"/>.</param>
/// <param name="parsableForPrimitives">Specifies what is generated for Parse and TryParse methods - defaults to <see cref="ParsableForPrimitives.HoistMethodsAndInterfaces"/>.</param>
/// <param name="tryFromGeneration">Specifies what to write for TryFrom methods—defaults to <see cref="TryFromGeneration.GenerateBoolAndErrorOrMethods"/>.</param>
/// <param name="isInitializedMethodGeneration">Specifies whether to generate an IsInitialized() method - defaults to <see cref="IsInitializedMethodGeneration.Generate"/>.</param>
/// <param name="primitiveEqualityGeneration">
/// Specifies whether to generate primitive comparison operators, allowing this type to be compared for equality to the primitive.
/// Defaults to <see cref="PrimitiveEqualityGeneration.GenerateOperatorsAndMethods"/>
/// <example>
/// <para>
/// var vo = MyInt.From(123);
/// </para>
/// <para>
/// bool same = vo == 123;
/// </para>
/// </example>
/// </param>
public ValueObjectAttribute(
Type? underlyingType = null!,
Conversions conversions = Conversions.Default,
Expand Down
1 change: 0 additions & 1 deletion src/Vogen.SharedTypes/ValueObjectOrError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public ValueObjectOrError(Validation error)
/// <summary>
/// Returns the wrapper, or throws an exception if the result failed.
/// </summary>
/// <typeparam name="T">The type of the wrapper.</typeparam>
/// <exception cref="System.InvalidOperationException">Throw when this type holds an error.</exception>
public T ValueObject =>
_isSuccess ? _valueObject : throw new System.InvalidOperationException("Cannot access the value object as it is not valid: " + _error!.ErrorMessage);
Expand Down
6 changes: 6 additions & 0 deletions src/Vogen.SharedTypes/Vogen.SharedTypes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@
<RootNamespace>Vogen</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DocumentationFile>bin\Debug\Vogen.SharedTypes.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DocumentationFile>bin\Release\Vogen.SharedTypes.xml</DocumentationFile>
</PropertyGroup>
</Project>
34 changes: 23 additions & 11 deletions src/Vogen.SharedTypes/VogenDefaultsAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// ReSharper disable UnusedType.Global

// ReSharper disable UnusedParameter.Local

namespace Vogen;

using System;
Expand All @@ -17,12 +18,12 @@ public class VogenDefaultsAttribute : Attribute
/// Creates a new instance of a type that represents the default
/// values used for value object generation.
/// </summary>
/// <param name="underlyingType">The primitive underlying type.</param>
/// <param name="conversions">Any conversions that need to be done for this type, e.g. to be serialized etc.</param>
/// <param name="throws">The type of exception that is thrown when validation fails.</param>
/// <param name="customizations">Any customizations, for instance, treating numbers in [de]serialization as strings.</param>
/// <param name="deserializationStrictness">The strictness of validation when deserializing.</param>
/// <param name="debuggerAttributes">Controls how debugger attributes are generated. This is useful in Rider where the attributes crash Rider's debugger.</param>
/// <param name="underlyingType">The type of the primitive that is being wrapped—defaults to int.</param>
/// <param name="conversions">Specifies what conversion code is generated - defaults to <see cref="Conversions.Default"/> which generates type converters and a converter to handle serialization using System.Text.Json</param>
/// <param name="throws">Specifies the type of exception thrown when validation fails—defaults to <see cref="ValueObjectValidationException"/>.</param>
/// <param name="customizations">Simple customization switches—defaults to <see cref="Customizations.None"/>.</param>
/// <param name="deserializationStrictness">Specifies how strict deserialization is, e.g. should your Validate method be called, or should pre-defined instances that otherwise invalid be allowed - defaults to <see cref="DeserializationStrictness.AllowValidAndKnownInstances"/>.</param>
/// <param name="debuggerAttributes">Specifies the level that debug attributes are written as some IDEs don't support all of them, e.g., Rider - defaults to <see cref="DebuggerAttributeGeneration.Full"/> which generates DebuggerDisplay and a debugger proxy type for IDEs that support them</param>
/// <param name="toPrimitiveCasting">Controls how cast operators are generated for casting from the Value Object to the primitive.
/// Options are implicit or explicit or none. Explicit is preferred over implicit if you really need them, but isn't recommended.
/// See <see href="https://github.com/SteveDunn/Vogen/wiki/Casting"/> for more information.</param>
Expand All @@ -31,15 +32,26 @@ public class VogenDefaultsAttribute : Attribute
/// See &lt;see href="https://github.com/SteveDunn/Vogen/wiki/Casting"/&gt; for more information.</param>
/// <param name="disableStackTraceRecordingInDebug">disables stack trace recording; in Debug builds, a stack trace is recorded and is
/// thrown in the exception when something is created in an uninitialized state, e.g. after deserialization</param>
/// <param name="parsableForStrings">Specifies the functionality around parsing (IParsable etc.)</param>
/// <param name="parsableForPrimitives">Specifies the functionality around parsing (IParsable etc.)</param>
/// <param name="tryFromGeneration">Controls what is generated for the TryFrom methods.</param>
/// <param name="isInitializedMethodGeneration">Controls whether the IsInitialized method is generated.</param>
/// <param name="parsableForStrings">Specifies what is generated for IParsable types for strings - defaults to <see cref="ParsableForStrings.GenerateMethodsAndInterface"/>.</param>
/// <param name="parsableForPrimitives">Specifies what is generated for Parse and TryParse methods - defaults to <see cref="ParsableForPrimitives.HoistMethodsAndInterfaces"/>.</param>
/// <param name="tryFromGeneration">Specifies what to write for TryFrom methods—defaults to <see cref="TryFromGeneration.GenerateBoolAndErrorOrMethods"/>.</param>
/// <param name="isInitializedMethodGeneration">Specifies whether to generate an IsInitialized() method - defaults to <see cref="IsInitializedMethodGeneration.Generate"/>.</param>
/// <param name="primitiveEqualityGeneration">
/// Specifies whether to generate primitive comparison operators, allowing this type to be compared for equality to the primitive.
/// Defaults to <see cref="PrimitiveEqualityGeneration.GenerateOperatorsAndMethods"/>
/// <example>
/// <para>
/// var vo = MyInt.From(123);
/// </para>
/// <para>
/// bool same = vo == 123;
/// </para>
/// </example>
/// </param>
/// <param name="systemTextJsonConverterFactoryGeneration">Controls the generation of the type factory for System.Text.Json.</param>
/// <param name="staticAbstractsGeneration">Controls the generation of static abstract interfaces.</param>
/// <param name="openApiSchemaCustomizations">Controls the generation of a Swashbuckle schema filter for OpenAPI.</param>
/// <param name="explicitlySpecifyTypeInValueObject">Every ValueObject attribute must explicitly specify the type of the primitive.</param>
/// <param name="primitiveEqualityGeneration">Whether or not to generate primitive comparison operators.</param>
public VogenDefaultsAttribute(
Type? underlyingType = null,
Conversions conversions = Conversions.Default,
Expand Down
14 changes: 13 additions & 1 deletion tests/Testbench/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using Vogen;
// ReSharper disable UnusedVariable

[assembly: VogenDefaults(
openApiSchemaCustomizations: OpenApiSchemaCustomizations.GenerateSwashbuckleSchemaFilter |
Expand All @@ -11,10 +15,11 @@

namespace Testbench;


[ValueObject<short>(conversions: Conversions.XmlSerializable)]
public partial class MyShort;

[ValueObject<int>(conversions: Conversions.XmlSerializable)]
[ValueObject<int>(conversions: Conversions.XmlSerializable, primitiveEqualityGeneration: PrimitiveEqualityGeneration.GenerateOperatorsAndMethods)]
public partial class MyInt;

[ValueObject<DateOnly>]
Expand Down Expand Up @@ -43,11 +48,18 @@ public static class Program
{
public static void Main()
{
MyInt i1 = MyInt.From(100);
MyInt i2 = MyInt.From(200);
bool smaller = i1.CompareTo(i2) < 0;
bool smaller2 = i1 == 100;

C c = new()
{
MyInt = MyInt.From(42),
MyShort = MyShort.From(123)
};



// C2 c = new()
// {
Expand Down

0 comments on commit 9f3981b

Please sign in to comment.