1use schemars::{
2 SchemaGenerator,
3 schema::{ArrayValidation, InstanceType, Schema, SchemaObject, SingleOrVec, StringValidation},
4};
5use serde::de::{self, Deserializer, Visitor};
6use std::fmt;
7
8/// Generates a JSON schema for a non-empty string array.
9pub fn non_empty_string_vec_json_schema(_: &mut SchemaGenerator) -> Schema {
10 Schema::Object(SchemaObject {
11 instance_type: Some(InstanceType::Array.into()),
12 array: Some(Box::new(ArrayValidation {
13 unique_items: Some(true),
14 items: Some(SingleOrVec::Single(Box::new(Schema::Object(
15 SchemaObject {
16 instance_type: Some(InstanceType::String.into()),
17 string: Some(Box::new(StringValidation {
18 min_length: Some(1), // Ensures string in the array is non-empty
19 ..Default::default()
20 })),
21 ..Default::default()
22 },
23 )))),
24 ..Default::default()
25 })),
26 format: Some("vec-of-non-empty-strings".to_string()), // Use a custom format keyword
27 ..Default::default()
28 })
29}
30
31/// Deserializes a non-empty string array.
32pub fn non_empty_string_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
33where
34 D: Deserializer<'de>,
35{
36 struct NonEmptyStringVecVisitor;
37
38 impl<'de> Visitor<'de> for NonEmptyStringVecVisitor {
39 type Value = Vec<String>;
40
41 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
42 formatter.write_str("a list of non-empty strings")
43 }
44
45 fn visit_seq<V>(self, mut seq: V) -> Result<Vec<String>, V::Error>
46 where
47 V: de::SeqAccess<'de>,
48 {
49 let mut vec = Vec::new();
50 while let Some(value) = seq.next_element::<String>()? {
51 if value.is_empty() {
52 return Err(de::Error::invalid_value(
53 de::Unexpected::Str(&value),
54 &"a non-empty string",
55 ));
56 }
57 vec.push(value);
58 }
59 Ok(vec)
60 }
61 }
62
63 deserializer.deserialize_seq(NonEmptyStringVecVisitor)
64}