flexml/
lib.rs

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