use std::fmt;
#[macro_export]
macro_rules! shape_id {
($ns:literal, $name:literal) => {
$crate::ShapeId::from_static(concat!($ns, "#", $name), $ns, $name)
};
($ns:literal, $name:literal, $member:literal) => {
$crate::ShapeId::from_static_with_member(
concat!($ns, "#", $name, "$", $member),
$ns,
$name,
$member,
)
};
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ShapeId {
fqn: &'static str,
namespace: &'static str,
shape_name: &'static str,
member_name: Option<&'static str>,
}
impl ShapeId {
#[doc(hidden)]
pub const fn from_static(
fqn: &'static str,
namespace: &'static str,
shape_name: &'static str,
) -> Self {
Self {
fqn,
namespace,
shape_name,
member_name: None,
}
}
#[doc(hidden)]
pub const fn from_static_with_member(
fqn: &'static str,
namespace: &'static str,
shape_name: &'static str,
member_name: &'static str,
) -> Self {
Self {
fqn,
namespace,
shape_name,
member_name: Some(member_name),
}
}
pub fn as_str(&self) -> &str {
self.fqn
}
pub fn namespace(&self) -> &str {
self.namespace
}
pub fn shape_name(&self) -> &str {
self.shape_name
}
pub fn member_name(&self) -> Option<&str> {
self.member_name
}
}
impl fmt::Display for ShapeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.fqn)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shape_id_macro() {
const ID: ShapeId = shape_id!("smithy.api", "String");
assert_eq!(ID.as_str(), "smithy.api#String");
assert_eq!(ID.namespace(), "smithy.api");
assert_eq!(ID.shape_name(), "String");
assert_eq!(ID.member_name(), None);
}
#[test]
fn test_shape_id_macro_with_member() {
const ID: ShapeId = shape_id!("com.example", "MyStruct", "field");
assert_eq!(ID.as_str(), "com.example#MyStruct$field");
assert_eq!(ID.namespace(), "com.example");
assert_eq!(ID.shape_name(), "MyStruct");
assert_eq!(ID.member_name(), Some("field"));
}
#[test]
fn test_display() {
let id = shape_id!("smithy.api", "String");
assert_eq!(format!("{id}"), "smithy.api#String");
}
#[test]
fn test_equality() {
let a = shape_id!("smithy.api", "String");
let b = shape_id!("smithy.api", "String");
assert_eq!(a, b);
let c = shape_id!("smithy.api", "String", "foo");
let d = shape_id!("smithy.api", "String", "foo");
assert_eq!(c, d);
}
}