use super::{ArgumentsList, Identifier, Span, WithIdentifier, WithSpan};
use std::ops::Index;
#[derive(Debug, Clone)]
pub struct Attribute {
pub name: Identifier,
pub arguments: ArgumentsList,
pub span: Span,
}
impl Attribute {
pub fn span_for_argument(&self, argument: &str) -> Option<Span> {
self.arguments
.iter()
.find(|a| a.name.as_ref().map(|n| n.name.as_str()) == Some(argument))
.map(|a| a.span)
}
}
impl WithIdentifier for Attribute {
fn identifier(&self) -> &Identifier {
&self.name
}
}
impl WithSpan for Attribute {
fn span(&self) -> Span {
self.span
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum AttributeContainer {
Model(super::ModelId),
ModelField(super::ModelId, super::FieldId),
Enum(super::EnumId),
EnumValue(super::EnumId, u32),
CompositeTypeField(super::CompositeTypeId, super::FieldId),
}
impl From<super::ModelId> for AttributeContainer {
fn from(v: super::ModelId) -> Self {
Self::Model(v)
}
}
impl From<(super::ModelId, super::FieldId)> for AttributeContainer {
fn from((model, field): (super::ModelId, super::FieldId)) -> Self {
Self::ModelField(model, field)
}
}
impl From<super::EnumId> for AttributeContainer {
fn from(v: super::EnumId) -> Self {
Self::Enum(v)
}
}
impl From<(super::CompositeTypeId, super::FieldId)> for AttributeContainer {
fn from((ct, field): (super::CompositeTypeId, super::FieldId)) -> Self {
Self::CompositeTypeField(ct, field)
}
}
impl From<(super::EnumId, u32)> for AttributeContainer {
fn from((enm, val): (super::EnumId, u32)) -> Self {
Self::EnumValue(enm, val)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct AttributeId(AttributeContainer, u32);
impl AttributeId {
pub fn new_in_container(container: AttributeContainer, idx: usize) -> AttributeId {
AttributeId(container, idx as u32)
}
}
impl Index<AttributeContainer> for super::SchemaAst {
type Output = [Attribute];
fn index(&self, index: AttributeContainer) -> &Self::Output {
match index {
AttributeContainer::Model(model_id) => &self[model_id].attributes,
AttributeContainer::ModelField(model_id, field_id) => &self[model_id][field_id].attributes,
AttributeContainer::Enum(enum_id) => &self[enum_id].attributes,
AttributeContainer::EnumValue(enum_id, value_idx) => &self[enum_id].values[value_idx as usize].attributes,
AttributeContainer::CompositeTypeField(ctid, field_id) => &self[ctid][field_id].attributes,
}
}
}
impl Index<AttributeId> for super::SchemaAst {
type Output = Attribute;
fn index(&self, index: AttributeId) -> &Self::Output {
&self[index.0][index.1 as usize]
}
}