microsoft/TypeAgent

Public

mirrored fromhttps://github.com/microsoft/TypeAgentAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
d4944c6517c9a96a3c419f827769f518913f1b75

Branches

Tags

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

Clone

HTTPS

Download ZIP

dotnet/autoShell/Handlers/ActionHandlerBase.cs

74lines · 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 return typed == null
62 ? ActionResult.Fail($"Invalid parameters for '{actionName}': null parameters not allowed")
63 : handler(typed);
64 });
65 }
66
67 /// <inheritdoc/>
68 public virtual ActionResult Handle(string key, JsonElement parameters)
69 {
70 return _actions.TryGetValue(key, out var handler)
71 ? handler(parameters)
72 : ActionResult.Fail($"Unknown action: {key}");
73 }
74}