1use serde::{Deserialize, Serialize};
2
3#[derive(
5 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize,
6)]
7#[serde(transparent)]
8pub struct TenantId(pub u64);
9
10#[cfg(feature = "utoipa")]
14impl<'s> utoipa::ToSchema<'s> for TenantId {
15 fn schema() -> (&'s str, utoipa::openapi::RefOr<utoipa::openapi::Schema>) {
16 ("TenantId", transparent_u64_schema("Tenant identifier."))
17 }
18}
19
20#[derive(
23 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize,
24)]
25#[serde(transparent)]
26pub struct ProjectId(pub u64);
27
28#[cfg(feature = "utoipa")]
29impl<'s> utoipa::ToSchema<'s> for ProjectId {
30 fn schema() -> (&'s str, utoipa::openapi::RefOr<utoipa::openapi::Schema>) {
31 ("ProjectId", transparent_u64_schema("Project identifier."))
32 }
33}
34
35#[cfg(feature = "utoipa")]
36fn transparent_u64_schema(description: &str) -> utoipa::openapi::RefOr<utoipa::openapi::Schema> {
37 use utoipa::openapi::schema::{ObjectBuilder, SchemaFormat, SchemaType};
38 ObjectBuilder::new()
39 .schema_type(SchemaType::Integer)
40 .format(Some(SchemaFormat::KnownFormat(
41 utoipa::openapi::KnownFormat::Int64,
42 )))
43 .minimum(Some(0.0))
44 .description(Some(description))
45 .into()
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
51#[serde(transparent)]
52pub struct Namespace(pub String);
53
54#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
56#[serde(transparent)]
57pub struct TypeName(pub String);
58
59impl TypeName {
60 pub fn qualified(ns: &Namespace, label: &str) -> Self {
62 if label.contains('.') {
63 Self(label.to_owned())
65 } else {
66 Self(format!("{}.{}", ns.0, label))
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
73#[serde(transparent)]
74pub struct VertexId(pub String);
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
78#[serde(transparent)]
79pub struct EdgeId(pub String);
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn qualified_name_prepends_namespace() {
87 let ns = Namespace("Antares".into());
88 assert_eq!(TypeName::qualified(&ns, "Deal").0, "Antares.Deal");
89 }
90
91 #[test]
92 fn qualified_name_is_idempotent() {
93 let ns = Namespace("Antares".into());
94 assert_eq!(TypeName::qualified(&ns, "Antares.Deal").0, "Antares.Deal");
95 }
96}