wdl_format/config/
quotes.rs1use std::fmt;
4use std::str::FromStr;
5
6use schemars::JsonSchema;
7use thiserror::Error;
8
9const DOUBLE_QUOTE: &str = "\"";
11const SINGLE_QUOTE: &str = "'";
13
14#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, JsonSchema)]
16#[schemars(rename_all = "lowercase")]
17pub enum QuoteStyle {
18 Double,
20 Single,
22 #[default]
24 Preserve,
25}
26
27impl fmt::Display for QuoteStyle {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 Self::Double => f.write_str("double"),
31 Self::Single => f.write_str("single"),
32 Self::Preserve => f.write_str("preserve"),
33 }
34 }
35}
36
37#[derive(Clone, Debug, Eq, Error, PartialEq)]
39#[error("invalid quote style `{0}`; expected one of: `double`, `single`, `preserve`")]
40pub struct ParseQuoteStyleError(String);
41
42impl FromStr for QuoteStyle {
43 type Err = ParseQuoteStyleError;
44
45 fn from_str(s: &str) -> Result<Self, Self::Err> {
46 match s.to_ascii_lowercase().as_str() {
47 "double" => Ok(Self::Double),
48 "single" => Ok(Self::Single),
49 "preserve" => Ok(Self::Preserve),
50 _ => Err(ParseQuoteStyleError(s.to_string())),
51 }
52 }
53}
54
55impl QuoteStyle {
56 pub fn as_str(&self) -> Option<&str> {
59 match self {
60 QuoteStyle::Preserve => None,
61 QuoteStyle::Double => Some(DOUBLE_QUOTE),
62 QuoteStyle::Single => Some(SINGLE_QUOTE),
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_double_quote() {
73 assert_eq!(QuoteStyle::Double.as_str(), Some("\""));
74 }
75
76 #[test]
77 fn test_single_quote() {
78 assert_eq!(QuoteStyle::Single.as_str(), Some("'"));
79 }
80
81 #[test]
82 fn test_preserve_quote() {
83 assert_eq!(QuoteStyle::Preserve.as_str(), None);
84 }
85
86 #[test]
87 fn test_default_is_preserve() {
88 assert!(matches!(QuoteStyle::default(), QuoteStyle::Preserve));
89 }
90
91 #[test]
92 fn from_str_accepts_valid_values() {
93 assert_eq!(
94 "preserve".parse::<QuoteStyle>().unwrap(),
95 QuoteStyle::Preserve
96 );
97 assert_eq!("double".parse::<QuoteStyle>().unwrap(), QuoteStyle::Double);
98 assert_eq!("single".parse::<QuoteStyle>().unwrap(), QuoteStyle::Single);
99 }
100
101 #[test]
102 fn from_str_rejects_invalid_value() {
103 let err = "bad".parse::<QuoteStyle>().unwrap_err();
104 assert_eq!(
105 err.to_string(),
106 "invalid quote style `bad`; expected one of: `double`, `single`, `preserve`"
107 );
108 }
109
110 #[test]
111 fn display_round_trips_through_from_str() {
112 for style in [QuoteStyle::Preserve, QuoteStyle::Double, QuoteStyle::Single] {
113 assert_eq!(style.to_string().parse::<QuoteStyle>().unwrap(), style);
114 }
115 }
116}