use crate::builder::id::ShapeName;
use crate::builder::traits::ErrorSource;
use crate::builder::{traits, TopLevelShapeBuilder, TraitBuilder};
use crate::model::shapes::Simple;
use crate::model::{Identifier, ShapeID};
use crate::prelude::{
PRELUDE_NAMESPACE, SHAPE_BIGDECIMAL, SHAPE_BIGINTEGER, SHAPE_BLOB, SHAPE_BOOLEAN, SHAPE_BYTE,
SHAPE_DOCUMENT, SHAPE_DOUBLE, SHAPE_FLOAT, SHAPE_INTEGER, SHAPE_LONG, SHAPE_SHORT,
SHAPE_STRING, SHAPE_TIMESTAMP,
};
use crate::syntax::{MEMBER_KEY, MEMBER_MEMBER, MEMBER_VALUE};
use std::collections::HashMap;
use std::ops::Deref;
use std::str::FromStr;
#[doc(hidden)]
macro_rules! add_trait {
($vis:vis $trait_fn:ident) => {
$vis fn $trait_fn(&mut self) -> &mut Self {
self.apply_trait(traits::$trait_fn().into())
}
};
($vis:vis $trait_fn:ident ( $( $i:ident : $t:ty ),* ) ) => {
$vis fn $trait_fn(&mut self, $( $i: $t ),* ) -> &mut Self {
self.apply_trait(traits::$trait_fn($( $i ),*).into())
}
};
}
macro_rules! from_impls {
($builder:ident, $variant:ident) => {
from_impls! { $builder }
impl From<$builder> for TopLevelShapeBuilder {
fn from(inner: $builder) -> Self {
TopLevelShapeBuilder::$variant(inner)
}
}
};
($builder:ident) => {
impl From<&mut $builder> for $builder {
fn from(v: &mut $builder) -> Self {
<$builder>::clone(<&mut $builder>::deref(&v))
}
}
};
}
macro_rules! shape_traits_impl {
($builder:ident) => {
impl ShapeTraits for $builder {
fn apply_trait(&mut self, a_trait: TraitBuilder) -> &mut Self {
self.applied_traits.push(a_trait);
self
}
}
};
}
#[derive(Clone, Debug)]
pub struct SimpleShapeBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) simple_shape: Simple,
}
#[derive(Clone, Debug)]
pub struct ListBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) member: MemberBuilder,
}
#[derive(Clone, Debug)]
pub struct MapBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) key: MemberBuilder,
pub(super) value: MemberBuilder,
}
#[derive(Clone, Debug)]
pub struct StructureBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) members: Vec<MemberBuilder>,
}
#[derive(Clone, Debug)]
pub struct ServiceBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) version: String,
pub(super) operations: Vec<ShapeName>,
pub(super) resources: Vec<ShapeName>,
pub(super) rename_shapes: HashMap<ShapeID, Identifier>,
}
#[derive(Clone, Debug)]
pub struct OperationBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) input: Option<ShapeName>,
pub(super) output: Option<ShapeName>,
pub(super) errors: Vec<ShapeName>,
}
#[derive(Clone, Debug)]
pub struct ResourceBuilder {
pub(super) shape_name: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) identifiers: HashMap<Identifier, ShapeName>,
pub(super) create: Option<ShapeName>,
pub(super) put: Option<ShapeName>,
pub(super) read: Option<ShapeName>,
pub(super) update: Option<ShapeName>,
pub(super) delete: Option<ShapeName>,
pub(super) list: Option<ShapeName>,
pub(super) operations: Vec<ShapeName>,
pub(super) collection_operations: Vec<ShapeName>,
pub(super) resources: Vec<ShapeName>,
}
#[derive(Clone, Debug)]
pub struct ReferenceBuilder {
pub(super) shape_id: ShapeName,
pub(super) applied_traits: Vec<TraitBuilder>,
}
#[derive(Clone, Debug)]
pub struct MemberBuilder {
pub(super) member_name: Identifier,
pub(super) applied_traits: Vec<TraitBuilder>,
pub(super) target: ShapeName,
}
pub trait ShapeTraits {
fn apply_trait(&mut self, a_trait: TraitBuilder) -> &mut Self
where
Self: Sized;
fn documentation(&mut self, text: &str) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::documentation(text))
}
fn external_documentation(&mut self, map: &[(&str, &str)]) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::external_documentation(map))
}
fn deprecated(&mut self, message: Option<&str>, since: Option<&str>) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::deprecated(message, since))
}
fn private(&mut self) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::private())
}
fn since(&mut self, date: &str) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::since(date))
}
fn tagged(&mut self, tags: &[&str]) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::tagged(tags))
}
fn unstable(&mut self) -> &mut Self
where
Self: Sized,
{
self.apply_trait(traits::unstable())
}
}
from_impls! { SimpleShapeBuilder, SimpleShape }
shape_traits_impl! { SimpleShapeBuilder }
impl SimpleShapeBuilder {
pub fn new(shape_name: &str, simple_shape: Simple) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
simple_shape,
}
}
pub fn blob(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Blob)
}
pub fn boolean(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Boolean)
}
pub fn document(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Document)
}
pub fn string(shape_name: &str) -> Self {
Self::new(shape_name, Simple::String)
}
pub fn byte(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Byte)
}
pub fn short(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Short)
}
pub fn integer(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Integer)
}
pub fn long(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Long)
}
pub fn float(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Float)
}
pub fn double(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Double)
}
pub fn big_integer(shape_name: &str) -> Self {
Self::new(shape_name, Simple::BigInteger)
}
pub fn big_decimal(shape_name: &str) -> Self {
Self::new(shape_name, Simple::BigDecimal)
}
pub fn timestamp(shape_name: &str) -> Self {
Self::new(shape_name, Simple::Timestamp)
}
add_trait!(pub boxed);
add_trait!(pub sensitive);
add_trait!(pub streaming);
}
from_impls! { ListBuilder }
shape_traits_impl! { ListBuilder }
impl ListBuilder {
pub fn new(shape_name: &str, member_target: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
member: MemberBuilder::new(MEMBER_MEMBER, member_target),
}
}
pub fn with_target(shape_name: &str, member_target: ShapeName) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
member: MemberBuilder::with_target(MEMBER_MEMBER, member_target),
}
}
pub fn target(&mut self, member: MemberBuilder) {
self.member = member;
}
add_trait!(pub sensitive);
add_trait!(pub unique_items);
}
from_impls! { MapBuilder, Map }
shape_traits_impl! { MapBuilder }
impl MapBuilder {
pub fn new(shape_name: &str, key_target: &str, value_target: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
key: MemberBuilder::new(MEMBER_KEY, key_target),
value: MemberBuilder::new(MEMBER_VALUE, value_target),
}
}
pub fn key(&mut self, key: MemberBuilder) {
self.key = key;
}
pub fn value(&mut self, value: MemberBuilder) {
self.value = value;
}
}
from_impls! { StructureBuilder }
shape_traits_impl! { StructureBuilder }
impl StructureBuilder {
pub fn new(shape_name: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
members: Default::default(),
}
}
pub fn member(&mut self, member_name: &str, member_target: &str) -> &mut Self {
let _ = self.add_member(MemberBuilder::new(member_name, member_target));
self
}
pub fn add_member(&mut self, member: MemberBuilder) -> &mut Self {
self.members.push(member);
self
}
pub fn blob(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_BLOB)
}
pub fn boolean(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_BOOLEAN)
}
pub fn document(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_DOCUMENT)
}
pub fn string(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_STRING)
}
pub fn byte(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_BYTE)
}
pub fn short(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_SHORT)
}
pub fn integer(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_INTEGER)
}
pub fn long(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_LONG)
}
pub fn float(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_FLOAT)
}
pub fn double(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_DOUBLE)
}
pub fn big_integer(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_BIGINTEGER)
}
pub fn big_decimal(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_BIGDECIMAL)
}
pub fn timestamp(&mut self, id: &str) -> &mut Self {
self.member(id, SHAPE_TIMESTAMP)
}
add_trait!(pub error_source(src: ErrorSource));
add_trait!(pub sensitive);
}
from_impls! { ServiceBuilder, Service }
shape_traits_impl! { ServiceBuilder }
impl ServiceBuilder {
pub fn new(shape_name: &str, version: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
version: version.to_string(),
operations: Default::default(),
resources: Default::default(),
rename_shapes: Default::default(),
}
}
pub fn version(&mut self, version: &str) -> &mut Self {
self.version = version.to_string();
self
}
pub fn operation(&mut self, shape_id: &str) -> &mut Self {
self.operations.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn operations(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.operation(shape_id);
}
self
}
pub fn resource(&mut self, shape_id: &str) -> &mut Self {
self.resources.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn resources(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.resource(shape_id);
}
self
}
pub fn rename(&mut self, shape_id: &str, local_name: &str) -> &mut Self {
let _ = self.rename_shapes.insert(
ShapeID::from_str(shape_id).unwrap(),
Identifier::from_str(local_name).unwrap(),
);
self
}
add_trait!(pub sensitive);
add_trait!(pub paginated(
input_token: Option<&str>,
output_token: Option<&str>,
items: Option<&str>,
page_size: Option<&str>));
add_trait!(pub title(title: &str));
}
from_impls! { OperationBuilder, Operation }
shape_traits_impl! { OperationBuilder }
impl OperationBuilder {
pub fn new(shape_name: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
input: None,
output: None,
errors: Default::default(),
}
}
pub fn input(&mut self, shape_id: &str) -> &mut Self {
self.input = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn output(&mut self, shape_id: &str) -> &mut Self {
self.output = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn error(&mut self, shape_id: &str) -> &mut Self {
self.errors.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn errors(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.error(shape_id);
}
self
}
add_trait!(pub idempotent);
add_trait!(pub readonly);
add_trait!(pub sensitive);
add_trait!(pub paginated(
input_token: Option<&str>,
output_token: Option<&str>,
items: Option<&str>,
page_size: Option<&str>));
}
from_impls! { ResourceBuilder, Resource }
shape_traits_impl! { ResourceBuilder }
impl ResourceBuilder {
pub fn new(shape_name: &str) -> Self {
Self {
shape_name: ShapeName::from_str(shape_name).unwrap(),
applied_traits: Default::default(),
identifiers: Default::default(),
create: None,
put: None,
read: None,
update: None,
delete: None,
list: None,
operations: vec![],
collection_operations: vec![],
resources: vec![],
}
}
pub fn identifier(&mut self, id: &str, shape_id: &str) -> &mut Self {
let _ = self.identifiers.insert(
Identifier::from_str(id).unwrap(),
ShapeName::from_str(shape_id).unwrap(),
);
self
}
pub fn create(&mut self, shape_id: &str) -> &mut Self {
self.create = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn put(&mut self, shape_id: &str) -> &mut Self {
self.put = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn read(&mut self, shape_id: &str) -> &mut Self {
self.read = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn update(&mut self, shape_id: &str) -> &mut Self {
self.update = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn delete(&mut self, shape_id: &str) -> &mut Self {
self.delete = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn list(&mut self, shape_id: &str) -> &mut Self {
self.list = Some(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn operation(&mut self, shape_id: &str) -> &mut Self {
self.operations.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn operations(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.operation(shape_id);
}
self
}
pub fn collection_operation(&mut self, shape_id: &str) -> &mut Self {
self.collection_operations
.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn collection_operations(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.collection_operation(shape_id);
}
self
}
pub fn resource(&mut self, shape_id: &str) -> &mut Self {
self.resources.push(ShapeName::from_str(shape_id).unwrap());
self
}
pub fn resources(&mut self, shape_ids: &[&str]) -> &mut Self {
for shape_id in shape_ids {
let _ = self.resource(shape_id);
}
self
}
add_trait!(pub sensitive);
add_trait!(pub no_replace);
add_trait!(pub title(title: &str));
}
from_impls! { ReferenceBuilder, Reference }
impl From<ShapeID> for ReferenceBuilder {
fn from(shape_id: ShapeID) -> Self {
Self {
shape_id: ShapeName::from(shape_id),
applied_traits: Default::default(),
}
}
}
shape_traits_impl! { ReferenceBuilder }
impl ReferenceBuilder {
pub fn new(shape_name: &str) -> Self {
let shape_id = ShapeID::from_str(shape_name).unwrap();
Self::from(shape_id)
}
}
from_impls! { MemberBuilder }
shape_traits_impl! { MemberBuilder }
impl MemberBuilder {
pub fn new(member_name: &str, target: &str) -> Self {
Self {
member_name: Identifier::from_str(member_name).unwrap(),
applied_traits: Default::default(),
target: ShapeName::from_str(target).unwrap(),
}
}
pub fn with_target(member_name: &str, target: ShapeName) -> Self {
Self {
member_name: Identifier::from_str(member_name).unwrap(),
applied_traits: Default::default(),
target,
}
}
fn new_unchecked(member_name: &str, target_namespace: &str, target_shape_name: &str) -> Self {
Self {
member_name: Identifier::from_str(member_name).unwrap(),
applied_traits: Default::default(),
target: ShapeName::Qualified(ShapeID::new_unchecked(
target_namespace,
target_shape_name,
None,
)),
}
}
pub fn name(&self) -> &Identifier {
&self.member_name
}
pub fn target(&self) -> &ShapeName {
&self.target
}
pub fn blob(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_BLOB)
}
pub fn boolean(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_BOOLEAN)
}
pub fn document(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_DOCUMENT)
}
pub fn string(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_STRING)
}
pub fn byte(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_BYTE)
}
pub fn short(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_SHORT)
}
pub fn integer(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_INTEGER)
}
pub fn long(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_LONG)
}
pub fn float(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_FLOAT)
}
pub fn double(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_DOUBLE)
}
pub fn big_integer(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_BIGINTEGER)
}
pub fn big_decimal(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_BIGDECIMAL)
}
pub fn timestamp(member_name: &str) -> Self {
Self::new_unchecked(member_name, PRELUDE_NAMESPACE, SHAPE_TIMESTAMP)
}
add_trait!(pub required);
}