Command Interpreters
После выполнения команды Pipeline получает CommandResultContext.
Дальнейшее поведение системы определяется интерпретаторами.
Интерпретаторы — это middleware,
работающие с CommandResultContext.
Именно они определяют:
какие типы
CommandResultподдерживаются в системе;как обрабатывается каждый результат;
каким образом завершается или продолжается выполнение.
—
Результаты выполнения команд
Все результаты наследуются от базового класса:
public abstract class CommandResult
{
public static CommandResult Exit => new ExitCommandResult();
}
В TeleFlow доступны следующие типы результатов:
ExitCommandResult
Завершает текущую команду.
Сессия пользователя удаляется, обработка продолжается без активной команды.
—
GoToStatefulResult
Используется внутри Stateful-команд для перехода к другому шагу.
public class GoToStatefulResult : CommandResult
{
public int GoToStepNumber { get; init; }
public bool InitializeNextStep { get; init; }
}
Позволяет:
установить номер шага;
указать, требуется ли его инициализация.
—
HoldOnStatefulResult
Оставляет выполнение на текущем шаге.
public class HoldOnStatefulResult : CommandResult
{
public HoldOnReason Reason { get; init; }
public string? HoldOnMessage { get; init; }
}
Используется, когда:
ввод пользователя некорректен;
требуется повторный ввод;
шаг только инициализируется.
Примечание
HoldOn не изменяет состояние шага
и не завершает команду.
—
Цепочка интерпретаторов
Интерпретаторы образуют отдельную цепочку middleware,
которая обрабатывает CommandResultContext.
Упрощённая схема:

Если ни один интерпретатор не обработал результат,
управление передаётся DefaultCommandInterpreter.
—
DefaultCommandInterpreter
public class DefaultCommandInterpreter
: IHandler<CommandResultContext>
{
private readonly IChatSessionStore _sessionStore;
public async Task Handle(CommandResultContext args)
{
var chatId = args.GetService<IChatIdProvider>()
.GetChatId();
await _sessionStore.RemoveAsync(chatId);
throw new Exception(
"No command interpreter matched the command result of type "
+ args.CommandResult.GetType().FullName);
}
}
Этот обработчик:
удаляет сессию;
сигнализирует об отсутствии интерпретатора для данного типа результата.
—
Навигационный интерпретатор
NavigateCommandResult обрабатывается
навигационным интерпретатором.
Его задача — выполнить переход к другой команде внутри текущего цикла обработки.
Алгоритм работы:
Завершает текущую команду (очищает сессию).
Создаёт новую
ChatSession.Создаёт целевую команду через
ICommandFactory.Запускает её с тем же
Update.Передаёт полученный результат во внутреннюю цепочку интерпретаторов.
Схема:

Фактически создаётся локальный цикл обработки, встроенный в текущий Pipeline.
—
Конфигурация интерпретаторов
Интерпретаторы настраиваются через
InterpreterPipelineBuilder.
Пример:
builder.WithNavigateInterpreter(3);
Можно добавлять собственные интерпретаторы
для обработки пользовательских типов CommandResult.
—
Когда писать собственный интерпретатор
Собственный интерпретатор требуется, если:
добавляется новый тип
CommandResult;изменяется семантика существующего результата;
требуется специфическая логика завершения команды.
Интерпретатор должен обрабатывать конкретный тип
CommandResult и быть включён в цепочку.