Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for type-safe enum pattern. #59

Open
Foxtrek64 opened this issue Aug 28, 2023 · 2 comments
Open

Support for type-safe enum pattern. #59

Foxtrek64 opened this issue Aug 28, 2023 · 2 comments
Labels
Feedback Needed Further information is requested General Enhancement New feature or request

Comments

@Foxtrek64
Copy link

I am building docs for my Electronic Data Interchange library. One of the files in this library uses the type-safe enum pattern in order to define Currency Codes.

When the API docs are rendered for this class, the static readonly members are listed, however their values are not readily available even after clicking on them. Where is the value of this property stored and how can it be recovered for viewing?

@daveaglick
Copy link
Member

Interesting - all the data is coming from Roslyn, and Statiq Docs essentially converts Roslyn symbols representations to Statiq Documents so we can more easily work with them. My guess is that the Docable theme doesn't know where to look for the value of these static readonly fields. Probably won't be too hard to add that - can you paste some code here showing exactly the pattern that you're using (I can probably guess, but want to make sure I'm replicating the problem exactly).

@daveaglick daveaglick added General Enhancement New feature or request Feedback Needed Further information is requested labels Sep 1, 2023
@Foxtrek64
Copy link
Author

Foxtrek64 commented Sep 1, 2023

I'm using a slightly modified version of Docable. Layout is mostly the same, but I've changed some properties here and there.

section/_Properties.cshtml

@{
    IReadOnlyList<IDocument> properties = Document.GetDocumentList(CodeAnalysisKeys.Members)
        ?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "Property")
        .OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
        .ToList()
        ?? new List<IDocument>();
    if (properties?.Count > 0)
    {
        List<(string, string)> headings = (List<(string, string)>?)ViewData[Keys.Headings] ?? new List<(string, string)>();
        headings.Add(("properties", "Properties"));
        ViewData[Keys.Headings] = headings;
        <h2 id="properties">Properties</h2>
        <div class="table-responsive">
            <table class="table table-api table-striped table-hover three-cols">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Property Type</th>
                        <th>Summary</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (IDocument property in properties)
                    {
                        <tr>
                            <td>@Context.GetTypeLink(property, false)</td>
                            <td>@Context.GetTypeLink(property.GetDocument(CodeAnalysisKeys.Type))</td>
                            <td>
                                <div>@Html.Raw(property.GetString(CodeAnalysisKeys.Summary))</div>
                                @{
                                    IDocument containingType = property.GetDocument(CodeAnalysisKeys.ContainingType);
                                    if (!Document.IdEquals(containingType))
                                    {
                                        <div><small><em>Inherited from @Context.GetTypeLink(containingType)</em></small></div>
                                    }
                                    if (property.GetBool(CodeAnalysisKeys.IsStatic))
                                    {
                                        <div><small><em>static</em></small></div>
                                    }
                                }
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
    }
}

section/_ConstantValue.cshtml

@using Microsoft.AspNetCore.Html;

@if (Document.GetBool(CodeAnalysisKeys.ConstantValue))
{
    List<(string, string)> headings = (List<(string, string)>?)ViewData[Keys.Headings] ?? new List<(string, string)>();
    headings.Add(("constant-value", "Constant Value"));
    ViewData[Keys.Headings] = headings;
	var constantValue = Document.Get(CodeAnalysisKeys.ConstantValue);

    <h2 id="constant-value">Constant Value</h2>
	<div class="table-responsive">
		<table class="table table-api table-striped table-hover two-cols">
			<thead>
				<tr>
					<th>Value</th>
					<th>Type</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>@(new HtmlString(constantValue?.ToString() ?? "null"))</td>
					<td>@(new HtmlString(constantValue?.GetType().Name ?? string.Empty))</td>
				</tr>
			</tbody>
		</table>
	</div>
}

Edit: Here's a small type-safe enum example:
Essentially, it aims to replicate Enum CustomerCode : T where T is anything, but it lacks some obvious features of enums such as being able to be used in a switch statement (values aren't constant), no flag support unless implemented manually, and so forth. Generally best used for when you need an explicit enumeration, such as where you'd use an enum, but where using an enum is not possible due to type restraints. These will be going away most likely when we get Discriminated Unions, but this is some time away.

public sealed class CustomerCode
{
    public string Code { get; }
    
    private CustomerCode(string code)
    {
        Code = code
    }

    public static readonly CustomerCode Contoso = new("Con01");
    public static readonly CustomerCode Microsoft = new ("Msft01");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feedback Needed Further information is requested General Enhancement New feature or request
Development

No branches or pull requests

2 participants