type_bridge_contract/
semantic_profile.rs1use crate::diagnostic::{Diagnostic, DiagnosticCategory};
4use crate::fingerprint::SemanticProfileId;
5use crate::value::Cardinality;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
9pub enum InterfaceKind {
10 Owns,
12 Relates,
14 Plays,
16}
17
18#[derive(Clone, Debug, Eq, PartialEq)]
20pub struct SemanticProfile {
21 id: SemanticProfileId,
22 owns_cardinality: Cardinality,
23 relates_cardinality: Cardinality,
24 plays_cardinality: Cardinality,
25 key_owns_cardinality: Cardinality,
26}
27
28impl SemanticProfile {
29 pub fn resolve(id: &SemanticProfileId) -> Result<Self, Diagnostic> {
31 match id.as_str() {
32 "typedb-3.11.5/v1" | "typedb-3.12.1/v1" => {
33 let bounded_to_one = Cardinality::new(0, Some(1))
34 .expect("the frozen zero-to-one cardinality is valid");
35 let unconstrained = Cardinality::new(0, None)
36 .expect("the frozen unconstrained cardinality is valid");
37 let exactly_one = Cardinality::new(1, Some(1))
38 .expect("the frozen exactly-one cardinality is valid");
39 Ok(Self {
40 id: id.clone(),
41 owns_cardinality: bounded_to_one,
42 relates_cardinality: bounded_to_one,
43 plays_cardinality: unconstrained,
44 key_owns_cardinality: exactly_one,
45 })
46 }
47 _ => Err(Diagnostic::stable(
48 DiagnosticCategory::UnsupportedCapability,
49 "unsupported_semantic_profile",
50 "semantic profile has no frozen schema-default table",
51 )),
52 }
53 }
54
55 #[must_use]
57 pub const fn id(&self) -> &SemanticProfileId {
58 &self.id
59 }
60
61 #[must_use]
63 pub const fn default_cardinality(&self, kind: InterfaceKind) -> Cardinality {
64 match kind {
65 InterfaceKind::Owns => self.owns_cardinality,
66 InterfaceKind::Relates => self.relates_cardinality,
67 InterfaceKind::Plays => self.plays_cardinality,
68 }
69 }
70
71 #[must_use]
73 pub const fn effective_cardinality(
74 &self,
75 kind: InterfaceKind,
76 explicit: Option<Cardinality>,
77 key: bool,
78 ) -> Cardinality {
79 match (kind, key, explicit) {
80 (InterfaceKind::Owns, true, _) => self.key_owns_cardinality,
81 (_, _, Some(cardinality)) => cardinality,
82 _ => self.default_cardinality(kind),
83 }
84 }
85}