Skip to main content

aws_smithy_http_server/
shape_id.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! A [`ShapeId`] represents a [Smithy Shape ID](https://smithy.io/2.0/spec/model.html#shape-id).
7//!
8//! # Example
9//!
10//! In the following model:
11//!
12//! ```smithy
13//! namespace smithy.example
14//!
15//! operation CheckHealth {}
16//! ```
17//!
18//! - `absolute` is `"smithy.example#CheckHealth"`
19//! - `namespace` is `"smithy.example"`
20//! - `name` is `"CheckHealth"`
21
22pub use crate::request::extension::{Extension, MissingExtension};
23
24/// Represents a [Smithy Shape ID](https://smithy.io/2.0/spec/model.html#shape-id).
25#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub struct ShapeId {
27    absolute: &'static str,
28    namespace: &'static str,
29    name: &'static str,
30}
31
32impl ShapeId {
33    /// Constructs a new [`ShapeId`]. This is used by the code-generator which preserves the invariants of the Shape ID format.
34    #[doc(hidden)]
35    pub const fn new(absolute: &'static str, namespace: &'static str, name: &'static str) -> Self {
36        Self {
37            absolute,
38            namespace,
39            name,
40        }
41    }
42
43    /// Converts a schema shape ID with static string components into a server shape ID.
44    ///
45    /// The strings are shared without allocating. The schema ID itself need not be borrowed
46    /// for `'static`, but its string components must be static because the server ID stores them.
47    ///
48    /// ```
49    /// use aws_smithy_http_server::ShapeId;
50    ///
51    /// const SCHEMA_ID: aws_smithy_schema::ShapeId<'static> =
52    ///     aws_smithy_schema::shape_id!("example", "Operation");
53    /// const ID: ShapeId = ShapeId::from_schema(&SCHEMA_ID);
54    ///
55    /// assert_eq!(ID.absolute(), SCHEMA_ID.as_str());
56    /// ```
57    pub const fn from_schema(id: &aws_smithy_schema::ShapeId<'static>) -> Self {
58        Self::new(id.as_str(), id.namespace(), id.shape_name())
59    }
60
61    /// Returns the namespace.
62    ///
63    /// See [Shape ID](https://smithy.io/2.0/spec/model.html#shape-id) for a breakdown of the syntax.
64    pub fn namespace(&self) -> &'static str {
65        self.namespace
66    }
67
68    /// Returns the member name.
69    ///
70    /// See [Shape ID](https://smithy.io/2.0/spec/model.html#shape-id) for a breakdown of the syntax.
71    pub fn name(&self) -> &'static str {
72        self.name
73    }
74
75    /// Returns the absolute shape ID.
76    ///
77    /// See [Shape ID](https://smithy.io/2.0/spec/model.html#shape-id) for a breakdown of the syntax.
78    pub fn absolute(&self) -> &'static str {
79        self.absolute
80    }
81}
82
83impl From<&aws_smithy_schema::ShapeId<'static>> for ShapeId {
84    fn from(id: &aws_smithy_schema::ShapeId<'static>) -> Self {
85        Self::from_schema(id)
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use crate::ShapeId;
92
93    #[test]
94    fn legacy_shape_id_api_is_available_at_the_crate_root() {
95        const ID: ShapeId = ShapeId::new("example#Operation", "example", "Operation");
96        assert_eq!(ID.absolute(), "example#Operation");
97        assert_eq!(ID.name(), "Operation");
98        assert_eq!(ID.namespace(), "example");
99    }
100
101    #[test]
102    fn schema_shape_id_converts_in_a_constant() {
103        const SCHEMA_ID: aws_smithy_schema::ShapeId<'static> = aws_smithy_schema::shape_id!("example", "Operation");
104        const ID: ShapeId = ShapeId::from_schema(&SCHEMA_ID);
105        assert_eq!(ID, ShapeId::new("example#Operation", "example", "Operation"));
106    }
107
108    #[test]
109    fn schema_shape_id_conversion_borrows_a_local_id() {
110        let schema_id = aws_smithy_schema::shape_id!("example", "Operation");
111        let id: ShapeId = (&schema_id).into();
112        assert_eq!(id.absolute(), schema_id.as_str());
113        assert_eq!(id.namespace(), schema_id.namespace());
114        assert_eq!(id.name(), schema_id.shape_name());
115        assert!(std::ptr::eq(id.absolute(), schema_id.as_str()));
116        assert!(std::ptr::eq(id.namespace(), schema_id.namespace()));
117        assert!(std::ptr::eq(id.name(), schema_id.shape_name()));
118    }
119}