use crate::model::shapes::{AppliedTraits, HasTraits, NonTraitEq};
use crate::model::values::Value;
use crate::model::{HasIdentity, Identifier, ShapeID};
use crate::syntax::{MEMBER_KEY, MEMBER_MEMBER, MEMBER_VALUE};
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq)]
pub struct MemberShape {
id: Identifier,
traits: AppliedTraits,
target: ShapeID,
}
#[derive(Clone, Debug, PartialEq)]
pub struct ListOrSet {
pub(crate) member: MemberShape,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Map {
pub(crate) key: MemberShape,
pub(crate) value: MemberShape,
}
#[derive(Clone, Debug, PartialEq)]
pub struct StructureOrUnion {
pub(crate) members: HashMap<Identifier, MemberShape>,
}
impl NonTraitEq for MemberShape {
fn equal_without_traits(&self, other: &Self) -> bool {
self.id() == other.id() && self.target() == other.target()
}
}
has_traits_impl! { MemberShape . traits }
impl HasIdentity<Identifier> for MemberShape {
fn id(&self) -> &Identifier {
&self.id
}
fn set_id(&mut self, id: Identifier) {
self.id = id
}
}
impl MemberShape {
pub fn new(id: Identifier, target: ShapeID) -> Self {
Self::with_traits(id, target, Default::default())
}
pub fn with_traits(
id: Identifier,
target: ShapeID,
traits: HashMap<ShapeID, Option<Value>>,
) -> Self {
Self { id, traits, target }
}
pub fn target(&self) -> &ShapeID {
&self.target
}
pub fn set_target(&mut self, target: ShapeID) {
self.target = target;
}
}
impl ListOrSet {
pub fn new(member_target: ShapeID) -> Self {
Self {
member: MemberShape::new(Identifier::new_unchecked(MEMBER_MEMBER), member_target),
}
}
pub fn from(member: MemberShape) -> Self {
assert_eq!(member.id().to_string(), MEMBER_MEMBER);
Self { member }
}
pub fn member(&self) -> &MemberShape {
&self.member
}
pub fn set_member(&mut self, member: MemberShape) {
assert_eq!(member.id(), self.member.id());
self.member = member
}
}
impl Map {
pub fn new(key_target: ShapeID, value_target: ShapeID) -> Self {
Self {
key: MemberShape::new(Identifier::new_unchecked(MEMBER_KEY), key_target),
value: MemberShape::new(Identifier::new_unchecked(MEMBER_VALUE), value_target),
}
}
pub fn from(key: MemberShape, value: MemberShape) -> Self {
Self { key, value }
}
pub fn key(&self) -> &MemberShape {
&self.key
}
pub fn set_key(&mut self, key: MemberShape) {
assert_eq!(key.id(), self.key.id());
self.key = key;
}
pub fn value(&self) -> &MemberShape {
&self.value
}
pub fn set_value(&mut self, value: MemberShape) {
assert_eq!(value.id(), self.value.id());
self.value = value;
}
}
impl Default for StructureOrUnion {
fn default() -> Self {
Self {
members: Default::default(),
}
}
}
impl StructureOrUnion {
pub fn new() -> Self {
Self::default()
}
pub fn with_members(members: &[MemberShape]) -> Self {
let mut new = Self {
members: Default::default(),
};
for member in members {
let _ = new.add_a_member(member.clone());
}
new
}
pub fn has_members(&self) -> bool {
!self.members.is_empty()
}
pub fn has_member(&self, member_name: &Identifier) -> bool {
!self.members.contains_key(member_name)
}
pub fn member(&self, member_name: &Identifier) -> Option<&MemberShape> {
self.members.get(member_name)
}
pub fn remove_member(&mut self, member_name: &Identifier) -> Option<MemberShape> {
self.members.remove(member_name)
}
pub fn members(&self) -> impl Iterator<Item = &MemberShape> {
self.members.values()
}
pub fn add_member(&mut self, member_name: Identifier, target: ShapeID) {
let shape = MemberShape::new(member_name, target);
let _ = self.add_a_member(shape);
}
pub fn add_a_member(&mut self, member: MemberShape) -> Option<MemberShape> {
self.members.insert(member.id().clone(), member)
}
}