microsoft/TypeAgent

Public

mirrored from https://github.com/microsoft/TypeAgentAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
55ef4624bfdb8b9c4f1b33c48e656f822c067e9b

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

dotnet/autoShell/Handlers/ActionHandlerBase.cs

76lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4using System;
5using System.Collections.Generic;
6using System.Text.Json;
7
8namespace autoShell.Handlers;
9
10/// <summary>
11/// Base class for all action handlers. Co-registers action names and handler functions
12/// via <see cref="AddAction"/> or <see cref="AddAction{T}"/>, providing automatic
13/// <see cref="SupportedActions"/> and dictionary-based dispatch.
14/// Subclasses register actions in their constructor.
15/// </summary>
16internal abstract class ActionHandlerBase : IActionHandler
17{
18 private static readonly JsonSerializerOptions CamelCaseOptions = new()
19 {
20 PropertyNameCaseInsensitive = true
21 };
22
23 private readonly Dictionary<string, Func<JsonElement, ActionResult>> _actions = new(StringComparer.OrdinalIgnoreCase);
24
25 /// <inheritdoc/>
26 public IEnumerable<string> SupportedActions => _actions.Keys;
27
28 /// <summary>
29 /// Registers an action name and its handler function. Throws if the name is already registered.
30 /// </summary>
31 protected void AddAction(string actionName, Func<JsonElement, ActionResult> handler)
32 {
33 if (!_actions.TryAdd(actionName, handler))
34 {
35 throw new InvalidOperationException(
36 $"Action '{actionName}' is already registered in {GetType().Name}.");
37 }
38 }
39
40 /// <summary>
41 /// Registers an action with a strongly-typed parameter record.
42 /// The <see cref="JsonElement"/> is automatically deserialized to <typeparamref name="T"/>.
43 /// </summary>
44 protected void AddAction<T>(string actionName, Func<T, ActionResult> handler)
45 {
46 AddAction(actionName, parameters =>
47 {
48 T typed;
49 try
50 {
51 if (parameters.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null)
52 {
53 return ActionResult.Fail($"Invalid parameters for '{actionName}': parameters are missing or null");
54 }
55 typed = JsonSerializer.Deserialize<T>(parameters.GetRawText(), CamelCaseOptions);
56 }
57 catch (JsonException ex)
58 {
59 return ActionResult.Fail($"Invalid parameters for '{actionName}': {ex.Message}");
60 }
61 if (typed == null)
62 {
63 return ActionResult.Fail($"Invalid parameters for '{actionName}': null parameters not allowed");
64 }
65 return handler(typed);
66 });
67 }
68
69 /// <inheritdoc/>
70 public virtual ActionResult Handle(string key, JsonElement parameters)
71 {
72 return _actions.TryGetValue(key, out var handler)
73 ? handler(parameters)
74 : ActionResult.Fail($"Unknown action: {key}");
75 }
76}
77