aws_smithy_schema/schema/
shape_id.rs1use std::borrow::Cow;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct ShapeId {
16 fqn: Cow<'static, str>,
17 namespace: Cow<'static, str>,
18 shape_name: Cow<'static, str>,
19}
20
21impl ShapeId {
22 pub const fn from_static(
26 fqn: &'static str,
27 namespace: &'static str,
28 shape_name: &'static str,
29 ) -> Self {
30 Self {
31 fqn: Cow::Borrowed(fqn),
32 namespace: Cow::Borrowed(namespace),
33 shape_name: Cow::Borrowed(shape_name),
34 }
35 }
36
37 pub fn new_from_parts(
46 namespace: impl Into<Cow<'static, str>>,
47 shape_name: impl Into<Cow<'static, str>>,
48 ) -> Self {
49 let namespace = namespace.into();
50 let shape_name = shape_name.into();
51 Self {
52 fqn: format!("{}#{}", namespace.as_ref(), shape_name.as_ref()).into(),
53 namespace,
54 shape_name,
55 }
56 }
57
58 pub fn new_from_fqn(fqn: impl Into<Cow<'static, str>>) -> Option<Self> {
60 let fqn = fqn.into();
61 let (namespace, shape_name) = fqn.as_ref().split_once('#').map(|(ns, rest)| {
62 (
63 ns.to_string(),
64 rest.split_once('$')
65 .map_or(rest, |(name, _)| name)
66 .to_string(),
67 )
68 })?;
69 Some(Self {
70 fqn,
71 namespace: namespace.into(),
72 shape_name: shape_name.into(),
73 })
74 }
75
76 pub fn new(fqn: impl Into<Cow<'static, str>>) -> Self {
78 Self::new_from_fqn(fqn).expect("invalid shape ID")
79 }
80
81 pub fn as_str(&self) -> &str {
83 self.fqn.as_ref()
84 }
85
86 pub fn namespace(&self) -> &str {
96 self.namespace.as_ref()
97 }
98
99 pub fn shape_name(&self) -> &str {
109 self.shape_name.as_ref()
110 }
111
112 pub fn member_name(&self) -> Option<&str> {
122 self.fqn
123 .split_once('#')
124 .and_then(|(_, rest)| rest.split_once('$').map(|(_, member)| member))
125 }
126}
127
128impl From<String> for ShapeId {
129 fn from(value: String) -> Self {
130 Self::new(value)
131 }
132}
133
134impl From<&str> for ShapeId {
135 fn from(value: &str) -> Self {
136 Self::new(value.to_string())
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn test_new() {
146 let shape_id = ShapeId::new("smithy.api#String");
147 assert_eq!(shape_id.as_str(), "smithy.api#String");
148 }
149
150 #[test]
151 fn test_namespace() {
152 assert_eq!(ShapeId::new("smithy.api#String").namespace(), "smithy.api");
153 assert_eq!(
154 ShapeId::new("com.example#MyStruct$member").namespace(),
155 "com.example"
156 );
157 }
158
159 #[test]
160 fn test_shape_name() {
161 assert_eq!(ShapeId::new("smithy.api#String").shape_name(), "String");
162 assert_eq!(
163 ShapeId::new("com.example#MyStruct$member").shape_name(),
164 "MyStruct"
165 );
166 }
167
168 #[test]
169 fn test_member_name() {
170 assert_eq!(
171 ShapeId::new("com.example#MyStruct$member").member_name(),
172 Some("member")
173 );
174 assert_eq!(ShapeId::new("smithy.api#String").member_name(), None);
175 }
176
177 #[test]
178 fn test_from_string() {
179 let shape_id: ShapeId = String::from("smithy.api#String").into();
180 assert_eq!(shape_id.as_str(), "smithy.api#String");
181 }
182
183 #[test]
184 fn test_from_str() {
185 let shape_id: ShapeId = "smithy.api#String".into();
186 assert_eq!(shape_id.as_str(), "smithy.api#String");
187 }
188
189 #[test]
190 fn test_clone_and_equality() {
191 let shape_id1 = ShapeId::new("smithy.api#String");
192 let shape_id2 = shape_id1.clone();
193 assert_eq!(shape_id1, shape_id2);
194 }
195}