use indexmap::IndexMap;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FieldType {
String,
Number,
Boolean,
Date,
Object,
Array,
GeoPoint,
File,
Bytes,
Polygon,
Pointer {
target_class: String,
},
Relation {
target_class: String,
},
Acl,
}
impl FieldType {
pub fn to_wire_string(&self) -> String {
match self {
FieldType::String => "String".into(),
FieldType::Number => "Number".into(),
FieldType::Boolean => "Boolean".into(),
FieldType::Date => "Date".into(),
FieldType::Object => "Object".into(),
FieldType::Array => "Array".into(),
FieldType::GeoPoint => "GeoPoint".into(),
FieldType::File => "File".into(),
FieldType::Bytes => "Bytes".into(),
FieldType::Polygon => "Polygon".into(),
FieldType::Acl => "ACL".into(),
FieldType::Pointer { target_class } => format!("Pointer<{target_class}>"),
FieldType::Relation { target_class } => format!("Relation<{target_class}>"),
}
}
pub fn is_pointer(&self) -> bool {
matches!(self, FieldType::Pointer { .. })
}
}
#[derive(Debug, Clone, Default)]
pub struct ClassSchema {
pub class_name: String,
pub fields: IndexMap<String, FieldType>,
}
impl ClassSchema {
pub fn new(class_name: impl Into<String>) -> Self {
Self {
class_name: class_name.into(),
fields: IndexMap::new(),
}
}
pub fn with_field(mut self, name: impl Into<String>, ty: FieldType) -> Self {
self.fields.insert(name.into(), ty);
self
}
pub fn field(&self, name: &str) -> Option<&FieldType> {
self.fields.get(name)
}
pub fn is_pointer_field(&self, name: &str) -> bool {
self.field(name).is_some_and(FieldType::is_pointer)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parametric_types_render_with_angle_brackets() {
assert_eq!(
FieldType::Pointer {
target_class: "_User".into()
}
.to_wire_string(),
"Pointer<_User>"
);
assert_eq!(
FieldType::Relation {
target_class: "Post".into()
}
.to_wire_string(),
"Relation<Post>"
);
assert_eq!(FieldType::String.to_wire_string(), "String");
}
#[test]
fn only_declared_pointer_fields_are_prefixed() {
let s = ClassSchema::new("Post").with_field(
"author",
FieldType::Pointer {
target_class: "_User".into(),
},
);
assert!(s.is_pointer_field("author"));
assert!(!s.is_pointer_field("undeclared"));
}
}