schema_registry_cli/settings/
subjects.rs

1use std::path::PathBuf;
2
3use clap::{Args, Subcommand};
4use schema_registry_api::{SchemaVersion, SubjectName};
5
6use crate::SchemaRegistrySettings;
7
8/// Subject commands
9#[derive(Debug, Clone, PartialEq, Subcommand)]
10pub enum SubjectSubCommand {
11    /// List subjects
12    List(ListSubjects),
13
14    /// Register schema
15    Register(RegisterSchemaSettings),
16
17    /// Check schema compatibility
18    Check(CheckCompatibility),
19
20    /// Delete subject
21    Delete(DeleteSubject),
22}
23
24impl Default for SubjectSubCommand {
25    fn default() -> Self {
26        Self::List(ListSubjects::default())
27    }
28}
29
30/// List subjects completions for shell
31#[derive(Debug, Clone, PartialEq, Default, Args)]
32pub struct ListSubjects {
33    /// The schema registry
34    #[clap(flatten)]
35    pub schema_registry: SchemaRegistrySettings,
36
37    /// Include deleted subjects
38    #[clap(long)]
39    pub all: bool,
40
41    /// Filter subjects with this prefix
42    pub prefix: Option<String>,
43}
44
45/// Register a schema to a subject
46#[derive(Debug, Clone, PartialEq, Args)]
47pub struct RegisterSchemaSettings {
48    /// The schema registry
49    #[clap(flatten)]
50    pub schema_registry: SchemaRegistrySettings,
51
52    /// The subject name, by default we use the file name
53    #[clap(short, long)]
54    pub subject: Option<SubjectName>,
55
56    /// Normalize the schema
57    #[clap(long)]
58    pub normalize: bool,
59
60    /// The schema file
61    pub path: PathBuf,
62}
63
64/// Delete subject
65#[derive(Debug, Clone, PartialEq, Args)]
66pub struct DeleteSubject {
67    /// The schema registry
68    #[clap(flatten)]
69    pub schema_registry: SchemaRegistrySettings,
70
71    /// The subject name
72    #[clap(short, long)]
73    pub subject: SubjectName,
74
75    /// The schema version
76    #[clap(long)]
77    pub version: Option<SchemaVersion>,
78
79    /// Delete permanent
80    #[clap(long)]
81    pub permanent: bool,
82}
83
84/// Check schema compatibility
85#[derive(Debug, Clone, PartialEq, Args)]
86pub struct CheckCompatibility {
87    /// The schema registry
88    #[clap(flatten)]
89    pub schema_registry: SchemaRegistrySettings,
90
91    /// The subject name, by default we use the file name
92    #[clap(short, long)]
93    pub subject: Option<SubjectName>,
94
95    /// The schema version
96    #[clap(long)]
97    pub version: Option<SchemaVersion>,
98
99    /// The schema file
100    pub path: PathBuf,
101}
102
103#[cfg(test)]
104mod tests {
105    use assert2::check;
106    use clap::Parser;
107
108    use crate::settings::DEFAULT_SCHEMA_REGISTRY_URL;
109
110    use super::*;
111
112    #[derive(Debug, Parser)]
113    struct JustSubject {
114        #[clap(subcommand)]
115        command: SubjectSubCommand,
116    }
117
118    #[rstest::rstest]
119    #[case::list(&["bin", "list"], SubjectSubCommand::List(ListSubjects { 
120        schema_registry: SchemaRegistrySettings {
121            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
122        },
123        all: false,
124        prefix: None,
125    }))]
126    #[case::list(&["bin", "list", "--all"], SubjectSubCommand::List(ListSubjects { 
127        schema_registry: SchemaRegistrySettings {
128            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
129        },
130        all: true,
131        prefix: None,
132    }))]
133    #[case::list(&["bin", "list", "plop-"], SubjectSubCommand::List(ListSubjects { 
134        schema_registry: SchemaRegistrySettings {
135            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
136        },
137        all: false,
138        prefix: Some("plop-".to_string()),
139    }))]
140    #[case::register(&["bin", "register", "--subject", "plop", "./plop-value.avsc"], SubjectSubCommand::Register(RegisterSchemaSettings { 
141        schema_registry: SchemaRegistrySettings {
142            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
143        },
144        subject: Some("plop".parse().unwrap()), 
145        normalize: false,
146        path: PathBuf::from("./plop-value.avsc"),
147    }))]
148    #[case::register(&["bin", "register", "./plop-value.avsc", "--normalize"], SubjectSubCommand::Register(RegisterSchemaSettings { 
149        schema_registry: SchemaRegistrySettings {
150            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
151        },
152        subject: None,
153        normalize: true,
154        path: PathBuf::from("./plop-value.avsc"),
155    }))]
156    #[case::check(&["bin", "check", "--subject", "plop", "./plop-value.avsc"], SubjectSubCommand::Check(CheckCompatibility { 
157        schema_registry: SchemaRegistrySettings {
158            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
159        },
160        subject: Some("plop".parse().unwrap()), 
161        version: None,
162        path: PathBuf::from("./plop-value.avsc"),
163    }))]
164    #[case::check(&["bin", "check", "-s", "plop", "--version", "42", "./plop-value.avsc"], SubjectSubCommand::Check(CheckCompatibility { 
165        schema_registry: SchemaRegistrySettings {
166            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
167        },
168        subject: Some("plop".parse().unwrap()), 
169        version: Some("42".parse().unwrap()),
170        path: PathBuf::from("./plop-value.avsc"),
171    }))]
172    #[case::delete(&["bin", "delete", "--subject", "plop"], SubjectSubCommand::Delete(DeleteSubject { 
173        schema_registry: SchemaRegistrySettings {
174            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
175        },
176        subject: "plop".parse().unwrap(), 
177        version: None,
178        permanent: false,
179    }))]
180    #[case::delete(&["bin", "delete", "-s", "plop", "--version", "42", "--permanent"], SubjectSubCommand::Delete(DeleteSubject { 
181        schema_registry: SchemaRegistrySettings {
182            url: DEFAULT_SCHEMA_REGISTRY_URL.parse().unwrap(),
183        },
184        subject: "plop".parse().unwrap(), 
185        version: Some("42".parse().unwrap()),
186        permanent: true,
187    }))]
188    fn should_parse_schema(#[case] args: &[&str], #[case] expected: SubjectSubCommand) {
189        let result = JustSubject::parse_from(args);
190        check!(result.command == expected);
191    }
192}