teo_runtime/model/relation/
relation.rs1use std::collections::BTreeMap;
2use std::sync::Arc;
3use serde::Serialize;
4use teo_parser::r#type::Type;
5use crate::comment::Comment;
6use crate::model::field::is_optional::IsOptional;
7use crate::model::field::typed::Typed;
8use crate::traits::named::Named;
9use crate::model::relation::delete::Delete;
10use crate::model::relation::update::Update;
11use crate::optionality::Optionality;
12use crate::traits::documentable::Documentable;
13use crate::value::Value;
14
15#[derive(Debug, Clone)]
16pub struct Relation {
17 pub(super) inner: Arc<Inner>
18}
19
20#[derive(Debug, Serialize)]
21pub(super) struct Inner {
22 pub(super) name: String,
23 pub(super) comment: Option<Comment>,
24 pub(super) r#type: Type,
25 pub(super) optionality: Optionality,
26 pub(super) model: Vec<String>,
27 pub(super) through: Option<Vec<String>>,
28 pub(super) local: Option<String>,
29 pub(super) foreign: Option<String>,
30 pub(super) is_vec: bool,
31 pub(super) fields: Vec<String>,
32 pub(super) references: Vec<String>,
33 pub(super) delete: Delete,
34 pub(super) update: Update,
35 pub(super) has_foreign_key: bool,
36 pub(super) data: BTreeMap<String, Value>,
37}
38
39impl Relation {
40
41 pub fn iter(&self) -> RelationIter {
42 RelationIter { index: 0, relation: self }
43 }
44
45 pub fn optionality(&self) -> &Optionality {
46 &self.inner.optionality
47 }
48
49 pub fn delete(&self) -> Delete {
50 self.inner.delete
51 }
52
53 pub fn update(&self) -> Update {
54 self.inner.update
55 }
56
57 pub fn has_foreign_key(&self) -> bool {
58 self.inner.has_foreign_key
59 }
60
61 pub fn model(&self) -> &Vec<String> {
62 &self.inner.model
63 }
64
65 pub fn is_vec(&self) -> bool {
66 self.inner.is_vec
67 }
68
69 pub fn through(&self) -> Option<&Vec<String>> {
70 self.inner.through.as_ref()
71 }
72
73 pub fn len(&self) -> usize {
74 self.inner.fields.len()
75 }
76
77 pub fn model_path(&self) -> &Vec<String> {
78 &self.inner.model
79 }
80
81 pub fn through_path(&self) -> Option<&Vec<String>> {
82 self.inner.through.as_ref()
83 }
84
85 pub fn local(&self) -> Option<&str> {
86 self.inner.local.as_ref().map(AsRef::as_ref)
87 }
88
89 pub fn foreign(&self) -> Option<&str> {
90 self.inner.foreign.as_ref().map(AsRef::as_ref)
91 }
92
93 pub fn has_join_table(&self) -> bool {
94 self.through_path().is_some()
95 }
96
97 pub fn fields(&self) -> &Vec<String> {
98 &self.inner.fields
99 }
100
101 pub fn references(&self) -> &Vec<String> {
102 &self.inner.references
103 }
104
105 pub fn data(&self) -> &BTreeMap<String, Value> {
106 &self.inner.data
107 }
108}
109
110impl Named for Relation {
111
112 fn name(&self) -> &str {
113 self.inner.name.as_str()
114 }
115}
116
117impl IsOptional for Relation {
118
119 fn is_optional(&self) -> bool {
120 self.inner.optionality.is_any_optional()
121 }
122
123 fn is_required(&self) -> bool {
124 self.inner.optionality.is_required()
125 }
126}
127
128pub struct RelationIter<'a> {
129 index: usize,
130 relation: &'a Relation,
131}
132
133impl<'a> Iterator for RelationIter<'a> {
134 type Item = (&'a str, &'a str);
135
136 fn next(&mut self) -> Option<Self::Item> {
137 if let Some(f) = self.relation.fields().get(self.index) {
138 let result = Some((f.as_str(), self.relation.references().get(self.index).unwrap().as_str()));
139 self.index += 1;
140 result
141 } else {
142 None
143 }
144 }
145}
146
147impl Documentable for Relation {
148
149 fn comment(&self) -> Option<&Comment> {
150 self.inner.comment.as_ref()
151 }
152
153 fn kind(&self) -> &'static str {
154 "relation"
155 }
156}
157
158impl Typed for Relation {
159
160 fn r#type(&self) -> &Type {
161 &self.inner.r#type
162 }
163}
164
165impl Serialize for Relation {
166
167 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> where S: serde::Serializer {
168 self.inner.serialize(serializer)
169 }
170}