use super::{Value, ValueLike, ValueType};
use std::collections::HashSet;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
pub struct FieldDefinition {
pub(super) name: String,
r#type: ValueType,
attributes: Vec<FieldAttribute>,
}
impl FieldDefinition {
pub fn new<N: Into<String>, T: Into<ValueType>>(name: N, r#type: T) -> Self {
Self::new_with_attributes(name, r#type, HashSet::new())
}
pub fn new_with_attributes<
N: Into<String>,
T: Into<ValueType>,
A: IntoIterator<Item = FieldAttribute>,
>(
name: N,
r#type: T,
attributes: A,
) -> Self {
let mut attributes: Vec<FieldAttribute> = attributes.into_iter().collect();
attributes.sort();
attributes.dedup();
Self {
name: name.into(),
r#type: r#type.into(),
attributes,
}
}
#[inline]
pub fn name(&self) -> &str {
&self.name
}
#[inline]
pub fn r#type(&self) -> &ValueType {
&self.r#type
}
#[inline]
pub fn attributes(&self) -> &[FieldAttribute] {
&self.attributes
}
#[inline]
pub fn is_indexed(&self) -> bool {
self.attributes().contains(&FieldAttribute::Indexed)
}
#[inline]
pub fn is_immutable(&self) -> bool {
self.attributes().contains(&FieldAttribute::Immutable)
}
#[inline]
pub fn is_computed(&self) -> bool {
self.attributes().contains(&FieldAttribute::Computed)
}
}
impl From<Field> for FieldDefinition {
fn from(field: Field) -> Self {
Self::new_with_attributes(field.name, field.value, field.attributes)
}
}
impl<'a> From<&'a Field> for FieldDefinition {
fn from(field: &'a Field) -> Self {
Self::new_with_attributes(field.name(), field.value(), field.attributes.clone())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
pub struct Field {
name: String,
value: Value,
attributes: Vec<FieldAttribute>,
}
impl Field {
pub fn new<N: Into<String>, V: ValueLike>(name: N, value: V) -> Self {
Self::new_with_attributes(name, value, HashSet::new())
}
pub fn new_with_attributes<
N: Into<String>,
V: ValueLike,
A: IntoIterator<Item = FieldAttribute>,
>(
name: N,
value: V,
attributes: A,
) -> Self {
let mut attributes: Vec<FieldAttribute> = attributes.into_iter().collect();
attributes.sort();
attributes.dedup();
Self {
name: name.into(),
value: value.into_value(),
attributes,
}
}
#[inline]
pub fn name(&self) -> &str {
&self.name
}
#[inline]
pub fn value(&self) -> &Value {
&self.value
}
#[inline]
pub fn value_mut(&mut self) -> &mut Value {
&mut self.value
}
#[inline]
pub fn into_value(self) -> Value {
self.value
}
pub fn to_value_type(&self) -> ValueType {
self.value.to_type()
}
#[inline]
pub fn attributes(&self) -> &[FieldAttribute] {
&self.attributes
}
#[inline]
pub fn is_indexed(&self) -> bool {
self.attributes().contains(&FieldAttribute::Indexed)
}
#[inline]
pub fn is_immutable(&self) -> bool {
self.attributes().contains(&FieldAttribute::Immutable)
}
#[inline]
pub fn is_computed(&self) -> bool {
self.attributes().contains(&FieldAttribute::Computed)
}
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "async-graphql", derive(async_graphql::Enum))]
pub enum FieldAttribute {
Indexed,
Immutable,
Computed,
}