В этом документе описывается архитектура продукта — парсера аргументов командной строки, разработанная на основании требований.
- Продукт не имеет системной архитектуры, поскольку его предполагается использовать в качестве подсистемы, встраиваемой в иные продукты.
---
title: Diagram of the system of the project
---
flowchart TB
nodeArgParser([ArgParser])
- Исходя из вышеуказанного предполагаемого использования продукта, весь продукт представляет собой одну подсистему — библиотеку argparser, которая должна обрабатывать данные аргументы командной строки.
---
title: Diagram of the module ArgParser
---
%%{
init: {
'theme': 'base',
'classDiagram': { 'curve': 'linear' },
}
}%%
classDiagram
direction TB
note for ArgParser "Has pseudonym functions for AddArgument and GetValue for each argument type"
class ArgParser {
-string name_;
-vector~ArgumentBuilder*~ argument_builders_;
-vector~Argument*~ arguments_;
-vector~string_view~ allowed_typenames_;
-vector~string~ allowed_typenames_for_help_;
-map~string_view, map~ string_view, size_t~~ arguments_by_type_;
-map~char, string_view~ short_to_long_names_;
-size_t help_index_;
+Parse(vector~string~ args, ConditionalOutput error_output=()) bool
+Parse(int argc, char[][] argv, ConditionalOutput error_output=()) bool
+Help() bool
+HelpDescription() string
+AddHelp(char short_name, string_view long_name, string description="") ConcreteArgumentBuilder~bool~ &
+AddHelp(string_view long_name, string description="") ConcreteArgumentBuilder~bool~ &
+AddArgument~T~(char short_name, string_view long_name, string description="") ConcreteArgumentBuilder~T~ &
+AddArgument~T~(string_view long_name, string description="") ConcreteArgumentBuilder~T~ &
+GetValue~T~(string_view long_name, size_t index=0) T
+SeSetAliasForType~T~(string alias) void
-Parse_(vector~string~ args, ConditionalOutput error_output) bool
-GetLongKeys(string_view current_argument) vector~string_view~
-ParsePositionalArguments(vector~string~ argv, const vector~size_t~ & used_positions) void
-HandleErrors(ConditionalOutput error_output) bool
-RefreshArguments() void
-AddArgument_~T~(char short_name, string_view long_name, string description) ConcreteArgumentBuilder~T~ &
-GetValue_~T~(string_view long_name, size_t index) T
}
class Argument {
<<interface>>
+ValidateArgument(vector~string~ argv, size_t position)* vector~size_t~
+CheckLimit()* bool
+GetValueStatus()* ArgumentParsingStatus
+GetType()* string_view
+GetInfo()* ArgumentInformation
+GetUsedValues()* size_t
+ClearStored()* void
#ObtainValue(vector~string~ argv, string& value_string, vector~size_t~ & used_values, size_t position)* size_t
}
class ArgumentBuilder {
<<interface>>
+GetInfo()* ArgumentInformation
+GetDefaultValue()* string
+build()* Argument*
}
class ConcreteArgument~T~ {
-ArgumentInformation info_
-ArgumentParsingStatus value_status_
-size_t value_counter_
-T value_
-T default_value_
-T* stored_value_
-vector~T~* stored_values_
+GetValue(size_t index) T
+ValidateArgument(vector~string~ argv, size_t position) vector~size_t~
+CheckLimit() bool
+GetValueStatus() ArgumentParsingStatus
+GetType() string_view
+GetInfo() ArgumentInformation
+GetUsedValues() size_t
+ClearStored() void
#ObtainValue(vector~string~ argv, string& value_string, vector~size_t~ & used_values, size_t position) size_t
}
class ConcreteArgumentBuilder~T~ {
-ArgumentInformation info_;
-T default_value_;
-T* stored_value_;
-vector~T~* stored_values_;
-bool was_created_temp_vector_;
+MultiValue(size_t min=0) ConcreteArgumentBuilder &
+Positional() ConcreteArgumentBuilder&
+StoreValue(T& value) ConcreteArgumentBuilder&
+StoreValues(vector~T~ & values) ConcreteArgumentBuilder&
+Default(T value) ConcreteArgumentBuilder&
+AddValidate(function~bool(string&)~ validate) ConcreteArgumentBuilder&
+AddIsGood(function~bool(string&)~ is_good) ConcreteArgumentBuilder&
+GetInfo() ArgumentInformation
+GetDefaultValue() string
+build() Argument*`
}
class ArgumentInformation {
+char short_key = kBadChar
+string_view long_key = ""
+string description = ""
+string_view type
+size_t minimum_values = 0
+bool is_multi_value = false
+bool is_positional = false
+bool has_store_values = false
+bool has_store_value = false
+bool has_default = false
+function~bool(string&)~ validate = &AlwaysTrue
++function~bool(string&)~ is_good = &AlwaysTrue
}
class ArgumentParsingStatus {
<<enumeration>>
NoArgument
InvalidArgument
InsufficientArguments
Success
}
ArgParser *-- Argument
ArgParser *-- ArgumentBuilder
ArgParser <.. ConcreteArgument
ArgParser <.. ConcreteArgumentBuilder
Argument <|.. ConcreteArgument
ArgumentBuilder <.. Argument
ArgumentBuilder <|.. ConcreteArgumentBuilder
ConcreteArgument *-- ArgumentInformation
ConcreteArgument *-- ArgumentParsingStatus
ConcreteArgumentBuilder <.. ConcreteArgument
ConcreteArgumentBuilder *-- ArgumentInformation
Эта подсистема представляет собой набор классов и связей между ними, которые выполняют непосредственно парсинг аргументов командной строки, передаваемых в подсистему. Все классы находятся в пространстве имён ArgumentParser.
Этот класс является основным классом модуля, именно с ним обычно взаимодействует пользователь. Он должен предоставлять следующие возможности: добавление обрабатываемого аргумента (любого из указанных) с указанным ключом, парсинг набора аргументов командной строки, а также функция добавления аргумента. Кроме того, должен иметь функцию составления справки и обрабатывать ошибки в синтаксисе аргументов командной строки, и, в некоторых случаях, выводить их.
Этот класс реализует паттерн проектирования "Builder": ссылки на объекты наследников этого класса должна возвращать функция добавления аргумента из ArgParser, к нему должен обращаться пользователь, добавляя информацию об аргументе. Должен реализовывать функции добавления любой информации про аргумент, представленные в тестах и функцию построения. Ему должен наследовать шаблонизированный класс конкретного Builder, который будет реализовывать вышеуказанный функционал для каждого из типов аргумента.
Этот класс является родительским классом для всех классов аргументов. Должен иметь функции возврата статуса парсинга и возврата информации об аргументе, а также функцию получения значения аргумента из аргументов командной строки. Необходимая информация, не изменяемая в процессе парсинга, должна храниться в виде экземпляра структуры. На данный момент реализованы аргументы всех базовых значащих типов (кроме 8-битных чисел), StringArgument и ComplexArgument (строка с валидацией и чтением пробелов).