wyvern_schema/
field_name.rs1use std::fmt;
4use std::ops::Deref;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct FieldNameError;
9
10impl fmt::Display for FieldNameError {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 f.write_str("field name must not be empty")
13 }
14}
15
16impl std::error::Error for FieldNameError {}
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24pub struct FieldName(String);
25
26impl FieldName {
27 pub fn new(value: impl Into<String>) -> Self {
33 match Self::try_new(value) {
34 Ok(name) => name,
35 Err(FieldNameError) => Self("_".into()),
36 }
37 }
38
39 pub fn try_new(value: impl Into<String>) -> Result<Self, FieldNameError> {
45 let value = value.into();
46 if value.is_empty() {
47 return Err(FieldNameError);
48 }
49 Ok(Self(value))
50 }
51
52 pub fn as_str(&self) -> &str {
54 &self.0
55 }
56}
57
58impl Deref for FieldName {
59 type Target = str;
60
61 fn deref(&self) -> &Self::Target {
62 &self.0
63 }
64}
65
66impl AsRef<str> for FieldName {
67 fn as_ref(&self) -> &str {
68 self.as_str()
69 }
70}
71
72impl fmt::Display for FieldName {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 self.0.fmt(f)
75 }
76}
77
78impl From<&str> for FieldName {
79 fn from(value: &str) -> Self {
80 Self::new(value)
81 }
82}
83
84impl From<String> for FieldName {
85 fn from(value: String) -> Self {
86 Self::new(value)
87 }
88}
89
90impl PartialEq<str> for FieldName {
91 fn eq(&self, other: &str) -> bool {
92 self.0 == other
93 }
94}
95
96impl PartialEq<&str> for FieldName {
97 fn eq(&self, other: &&str) -> bool {
98 self.0 == *other
99 }
100}
101
102impl serde::Serialize for FieldName {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: serde::Serializer,
106 {
107 serializer.serialize_str(self.as_str())
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn try_new_rejects_empty() {
117 assert_eq!(FieldName::try_new("").unwrap_err(), FieldNameError);
118 assert_eq!(FieldName::try_new("title").unwrap().as_str(), "title");
119 }
120
121 #[test]
122 fn new_maps_empty_to_underscore() {
123 assert_eq!(FieldName::new("").as_str(), "_");
124 assert_eq!(FieldName::new("file").as_str(), "file");
125 }
126}