flexml/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod data;
4mod into_xml;
5mod namespace;
6mod node;
7
8pub use data::*;
9pub use into_xml::*;
10pub use namespace::*;
11
12#[cfg(any(feature = "macro", test))]
13pub use flexml_macro as macros;
14
15use heck::{
16    ToKebabCase, ToLowerCamelCase, ToShoutyKebabCase, ToShoutySnakeCase as _, ToSnakeCase,
17    ToTrainCase, ToUpperCamelCase,
18};
19
20use std::{
21    error::Error,
22    fmt::{self, Debug, Display},
23};
24
25#[derive(Debug)]
26pub enum XMLError {
27    NamespaceNotFound(String),
28    NamespaceOnText,
29    Other(String),
30}
31
32impl Display for XMLError {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        type S = XMLError;
35
36        match self {
37            S::NamespaceNotFound(v) => write!(
38                f,
39                "XMLError::NamespaceNotFound - Namespace \"{v}\" not defined"
40            ),
41            S::Other(v) => write!(f, "XMLError::Other \"{v}\""),
42            XMLError::NamespaceOnText => write!(
43                f,
44                "XMLError::NamespaceOnText \"Cannot set namespace on text node.\""
45            ),
46        }
47    }
48}
49
50impl<T: Error + Display> From<T> for XMLError {
51    fn from(value: T) -> Self {
52        Self::Other(value.to_string())
53    }
54}
55
56pub(crate) fn conv_case<T: Display, U: Display>(input: T, case: U) -> String {
57    let input = input.to_string();
58    match case.to_string().as_str() {
59        "KebabCase" | "kebab-kase" => input.to_kebab_case(),
60        "LowerCamelCase" | "lowerCamelCase" => input.to_lower_camel_case(),
61        "ShoutyKebabCase" | "SHOUTY-KEBAB-CASE" => input.to_shouty_kebab_case(),
62        // "snek" - What chicanery, what shenanigans - and dare I say it - what tomfoolery!
63        "ShoutySnakeCase" | "SHOUTY_SNAKE_CASE" | "ShoutySnekCase" | "SHOUTY_SNEK_CASE" => {
64            input.to_shouty_snake_case()
65        }
66        "SnakeCase" | "snake_case" | "SnekCase" | "snek_case" => input.to_snake_case(),
67
68        "TitleCase" | "Title Case" => {
69            panic!("XML does not allow the 'Title Case' casing scheme.")
70        }
71        "TrainCase" | "Train-Case" => input.to_train_case(),
72        "UpperCamelCase" | "PascalCase" => input.to_upper_camel_case(),
73        r => panic!("Unknown case '{r}'"),
74    }
75}