botocore_parser 0.1.0

Helper crate for parsin AWS JSON service definitions
use std::collections::BTreeMap;

#[derive(Serialize, Deserialize, Debug)]
pub struct Service {
    pub version: String,
    pub metadata: Metadata,
    pub documentation: Option<String>,
    pub operations: BTreeMap<String, Operation>,
    pub shapes: BTreeMap<String, Shape>,
    pub examples: BTreeMap<String, String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct HttpRequest {
    pub method: String,
    pub requestUri: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InputOutput {
    pub shape: String,
    pub documentation: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Error {
    pub shape: String,
    pub exception: bool,
    pub fault: Option<bool>,
    pub documentation: Option<String>,
    pub error: Option<HttpError>
}

#[derive(Serialize, Deserialize, Debug)]
pub struct HttpError {
    code: String,
    httpStatusCode: i32,
    senderFault: Option<bool>
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Member {
    pub shape: String,
    pub documentation: Option<String>,
    pub location: Option<String>,
    pub locationName: Option<String>,
    pub deprecated: Option<bool>,
    pub xmlNamespace: Option<XmlNamespace>,
    pub streaming: Option<bool>,
    pub xmlAttribute: Option<bool>
}

#[derive(Serialize, Deserialize, Debug)]
pub struct XmlNamespace {
    pub uri: String,
    pub prefix: Option<String>
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Key {
    pub shape: String,
}


#[derive(Serialize, Deserialize, Debug)]
pub struct Value {
    pub shape: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Shape {
    #[serde(rename="type")]
    pub shape_type: String,
    #[serde(rename="enum")]
    pub shape_enum: Vec<String>,
    pub required: Option<Vec<String>>,
    pub members: BTreeMap<String, Member>,
    pub member: Option<Member>,
    pub key: Option<Key>,
    pub value: Option<Value>,
    pub min: Option<i32>,
    pub max: Option<i32>,
    pub sensitive: Option<bool>,
    pub pattern: Option<String>,
    pub exception: Option<bool>,
    pub fault: Option<bool>,
    pub documentation: Option<String>,
    pub error: Option<HttpError>,
    pub flattened: Option<bool>,
    pub payload: Option<String>,
    pub timestampFormat: Option<String>,
    pub xmlNamespace: Option<XmlNamespace>
}

impl<'a> Shape {
    pub fn key(&'a self) -> &'a str {
        &self.key.as_ref().expect("Key shape undefined").shape
    }

    pub fn value(&'a self) -> &'a str {
        &self.value.as_ref().expect("Value shape undefined").shape
    }

    pub fn member(&'a self) -> &'a str {
        &self.member.as_ref().expect("Member shape undefined").shape
    }

    pub fn required(&self, field: &'a str) -> bool {
        self.required.is_some() && self.required.as_ref().unwrap().contains(&String::from(field))
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Operation {
    pub name: String,
    pub http: HttpRequest,
    pub input: Option<InputOutput>,
    pub output: Option<InputOutput>,
    pub errors: Vec<Error>,
    pub documentation: Option<String>,
    pub documentationUrl: Option<String>,
    pub alias: Option<String>,
    pub deprecated: Option<bool>
}

impl<'a> Operation {
    pub fn input_shape(&'a self) -> &'a str {
        &self.input.as_ref().expect("Operation input undefined").shape
    }

    pub fn output_shape_or(&'a self, default: &'a str) -> &'a str {
        match self.output.as_ref() {
            Some(output) => &output.shape,
            None => default
        }
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Metadata {
    pub apiVersion: String,
    pub endpointPrefix: String,
    pub jsonVersion: Option<String>,
    pub serviceAbbreviation: String,
    pub serviceFullName: String,
    pub signatureVersion: String,
    pub targetPrefix: Option<String>,
    pub protocol: String,
    pub checksumFormat: Option<String>,
    pub globalEndpoint: Option<String>,
    pub timestampFormat: Option<String>
}