use super::{CompositeTypeFieldWalker, ModelWalker, RelationFieldWalker, ScalarFieldWalker, Walker};
use crate::{
types::{RelationField, ScalarField},
ScalarType,
};
use schema_ast::ast;
pub type FieldWalker<'db> = Walker<'db, (ast::ModelId, ast::FieldId)>;
impl<'db> FieldWalker<'db> {
pub fn ast_field(self) -> &'db ast::Field {
&self.db.ast[self.id.0][self.id.1]
}
pub fn name(self) -> &'db str {
self.ast_field().name()
}
pub fn model(self) -> ModelWalker<'db> {
self.walk(self.id.0)
}
pub fn refine(self) -> RefinedFieldWalker<'db> {
match self.db.types.refine_field(self.id) {
either::Either::Left(id) => RefinedFieldWalker::Relation(self.walk(id)),
either::Either::Right(id) => RefinedFieldWalker::Scalar(self.walk(id)),
}
}
}
#[derive(Copy, Clone)]
pub enum RefinedFieldWalker<'db> {
Scalar(ScalarFieldWalker<'db>),
Relation(RelationFieldWalker<'db>),
}
impl<'db> From<ScalarFieldWalker<'db>> for FieldWalker<'db> {
fn from(w: ScalarFieldWalker<'db>) -> Self {
let ScalarField { model_id, field_id, .. } = w.db.types[w.id];
Walker {
db: w.db,
id: (model_id, field_id),
}
}
}
impl<'db> From<RelationFieldWalker<'db>> for FieldWalker<'db> {
fn from(w: RelationFieldWalker<'db>) -> Self {
let RelationField { model_id, field_id, .. } = w.db.types[w.id];
Walker {
db: w.db,
id: (model_id, field_id),
}
}
}
#[derive(Copy, Clone)]
enum InnerTypedFieldWalker<'db> {
Scalar(ScalarFieldWalker<'db>),
Composite(CompositeTypeFieldWalker<'db>),
}
impl<'db> From<ScalarFieldWalker<'db>> for TypedFieldWalker<'db> {
fn from(w: ScalarFieldWalker<'db>) -> Self {
Self {
inner: InnerTypedFieldWalker::Scalar(w),
}
}
}
impl<'db> From<CompositeTypeFieldWalker<'db>> for TypedFieldWalker<'db> {
fn from(w: CompositeTypeFieldWalker<'db>) -> Self {
Self {
inner: InnerTypedFieldWalker::Composite(w),
}
}
}
#[derive(Clone, Copy)]
pub struct TypedFieldWalker<'db> {
inner: InnerTypedFieldWalker<'db>,
}
impl<'db> TypedFieldWalker<'db> {
pub fn scalar_type(self) -> Option<ScalarType> {
match self.inner {
InnerTypedFieldWalker::Scalar(field) => field.scalar_type(),
InnerTypedFieldWalker::Composite(field) => field.scalar_type(),
}
}
pub fn raw_native_type(self) -> Option<(&'db str, &'db str, &'db [String], ast::Span)> {
match self.inner {
InnerTypedFieldWalker::Scalar(sf) => sf.raw_native_type(),
InnerTypedFieldWalker::Composite(cf) => cf.raw_native_type(),
}
}
}