Skip to main content

systemprompt_cli/shared/
parsers.rs

1//! CLI value parsers for fail-fast validation at command line boundaries.
2//!
3//! Each parser is a clap `value_parser`: a malformed identifier is rejected
4//! while the arguments are parsed, so it surfaces as a usage error instead of
5//! reaching a command body.
6//!
7//! Copyright (c) systemprompt.io — Business Source License 1.1.
8//! See <https://systemprompt.io> for licensing details.
9
10use systemprompt_identifiers::error::IdValidationError;
11use systemprompt_identifiers::{
12    AgentName, AiRequestId, ApiKeyId, CampaignId, CategoryId, Email, ExtensionId, JobName,
13    LinkClickId, LinkId, McpServerId, McpToolName, ModelId, PluginId, ProfileName, ProviderId,
14    SecretName, ServiceName, SkillId, TenantId, TraceId,
15};
16
17macro_rules! id_parsers {
18    ($($fn_name:ident => $ty:ident),* $(,)?) => {
19        $(
20            pub fn $fn_name(s: &str) -> Result<$ty, IdValidationError> {
21                $ty::try_new(s)
22            }
23        )*
24    };
25}
26
27id_parsers! {
28    parse_profile_name => ProfileName,
29    parse_email => Email,
30    parse_extension_id => ExtensionId,
31    parse_agent_name => AgentName,
32    parse_ai_request_id => AiRequestId,
33    parse_api_key_id => ApiKeyId,
34    parse_campaign_id => CampaignId,
35    parse_category_id => CategoryId,
36    parse_job_name => JobName,
37    parse_link_click_id => LinkClickId,
38    parse_link_id => LinkId,
39    parse_mcp_server_id => McpServerId,
40    parse_mcp_tool_name => McpToolName,
41    parse_plugin_id => PluginId,
42    parse_service_name => ServiceName,
43    parse_tenant_id => TenantId,
44    parse_trace_id => TraceId,
45    parse_provider_id => ProviderId,
46    parse_model_id => ModelId,
47    parse_secret_name => SecretName,
48    parse_skill_id => SkillId,
49}
50
51// Why: clap stores a subcommand `--profile` and the global `--profile` in one
52// value slot under the shared id, and the global flag reads that slot as a
53// `String`; a subcommand flag must therefore store a `String` too. This parser
54// still rejects anything that is not a valid profile name.
55pub fn parse_profile_name_arg(s: &str) -> Result<String, IdValidationError> {
56    ProfileName::try_new(s).map(|name| name.as_str().to_owned())
57}