donet_core/
dcfield.rs

1/*
2    This file is part of Donet.
3
4    Copyright © 2024-2025 Max Rodriguez <[email protected]>
5
6    Donet is free software; you can redistribute it and/or modify
7    it under the terms of the GNU Affero General Public License,
8    as published by the Free Software Foundation, either version 3
9    of the License, or (at your option) any later version.
10
11    Donet is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14    GNU Affero General Public License for more details.
15
16    You should have received a copy of the GNU Affero General Public
17    License along with Donet. If not, see <https://www.gnu.org/licenses/>.
18*/
19
20//! Base data model for DC Field elements. Alone, it represents
21//! an attribute of a structure or Distributed Class.
22
23use crate::datagram::datagram::Datagram;
24use crate::dcatomic::DCAtomicField;
25use crate::dckeyword::{DCKeywordList, IdentifyKeyword};
26use crate::dcmolecular::DCMolecularField;
27use crate::dctype::DCTypeDefinition;
28use crate::globals;
29use crate::hashgen::*;
30
31/// Enumerator representing the 3 types of fields that inherit DC Field,
32/// which can legally be declared within a Distributed Class.
33///
34/// Plain DC Fields represent a property, or member, of a structure
35/// or class. DC fields have a data type assigned to them.
36///
37/// DC Atomic Fields represent a method of a Distributed Class, which
38/// is always implemented as a remote procedure call (RPC). Unlike
39/// attribute fields, atomic fields cannot be declared within structs.
40///
41/// DC Molecular Fields represent a collection of one or more
42/// DC Atomic Fields as one field under one identifier. The parameters
43/// of a molecular field are the parameters of all the fields it
44/// represents, joined together in the order in which they were declared
45/// when the molecular field was declared.
46#[derive(Debug)]
47pub enum ClassField {
48    Field(DCField),
49    Atomic(DCAtomicField),
50    Molecular(DCMolecularField),
51}
52
53/// Macro for Panda historical keywords inline functions.
54macro_rules! has_keyword {
55    ($self:ident, $i:literal) => {
56        $self
57            .keyword_list
58            .has_keyword(IdentifyKeyword::ByName($i.to_owned()))
59    };
60}
61
62/// A field of a Distributed Class. The DCField struct is a base for
63/// struct and dclass fields. In the DC language, there are three types
64/// of field declarations, which are: plain fields, atomic, and molecular.
65#[derive(Debug)]
66pub struct DCField {
67    keyword_list: DCKeywordList,
68    field_name: String,
69    field_id: globals::FieldId,
70    field_type: DCTypeDefinition,
71    default_value_stale: bool,
72    has_default_value: bool,
73    default_value: Vec<u8>, // stored as byte array
74    bogus_field: bool,
75}
76
77impl std::fmt::Display for DCField {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        writeln!(f, "TODO")
80    }
81}
82
83impl LegacyDCHash for DCField {
84    fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
85        hashgen.add_int(self.field_id.into());
86        hashgen.add_string(self.field_name.clone());
87
88        self.field_type.clone().generate_hash(hashgen);
89        self.keyword_list.generate_hash(hashgen);
90    }
91}
92
93impl DCField {
94    #[inline(always)]
95    pub fn get_field_id(&self) -> globals::FieldId {
96        self.field_id
97    }
98
99    #[inline(always)]
100    pub fn get_field_name(&self) -> String {
101        self.field_name.clone()
102    }
103
104    #[inline(always)]
105    pub fn has_default_value(&self) -> bool {
106        self.has_default_value
107    }
108
109    pub fn validate_ranges(&self, _packed_data: &Datagram) -> bool {
110        todo!()
111    }
112
113    /// Given a blob that represents the packed data for this field, returns a
114    /// string formatting it for human consumption.
115    pub fn format_packed_data(
116        &self,
117        f: &mut std::fmt::Formatter<'_>,
118        _data: &[u8],
119        _show_field_names: bool,
120    ) -> std::fmt::Result {
121        f.write_str("TODO") // TODO
122    }
123
124    #[inline(always)]
125    pub fn is_bogus_field(&self) -> bool {
126        self.bogus_field
127    }
128
129    #[inline(always)]
130    pub fn is_required(&self) -> bool {
131        has_keyword!(self, "required")
132    }
133
134    #[inline(always)]
135    pub fn is_broadcast(&self) -> bool {
136        has_keyword!(self, "broadcast")
137    }
138
139    #[inline(always)]
140    pub fn is_ram(&self) -> bool {
141        has_keyword!(self, "ram")
142    }
143
144    #[inline(always)]
145    pub fn is_db(&self) -> bool {
146        has_keyword!(self, "db")
147    }
148
149    #[inline(always)]
150    pub fn is_clsend(&self) -> bool {
151        has_keyword!(self, "clsend")
152    }
153
154    #[inline(always)]
155    pub fn is_clrecv(&self) -> bool {
156        has_keyword!(self, "clrecv")
157    }
158
159    #[inline(always)]
160    pub fn is_ownsend(&self) -> bool {
161        has_keyword!(self, "ownsend")
162    }
163
164    #[inline(always)]
165    pub fn is_ownrecv(&self) -> bool {
166        has_keyword!(self, "ownrecv")
167    }
168
169    #[inline(always)]
170    pub fn is_airecv(&self) -> bool {
171        has_keyword!(self, "airecv")
172    }
173
174    fn _refresh_default_value(&self) {
175        todo!()
176    }
177}