<NME> service.rs
<BEF> use std::collections::BTreeMap;

use crate::botocore::{Member, Operation, ServiceDefinition, Shape, ShapeType, Value};
use crate::cargo;
use crate::config::ServiceConfig;

#[derive(Debug)]
pub struct Service<'a> {
    config: &'a crate::ServiceConfig,
    definition: ServiceDefinition,
}

impl<'b> Service<'b> {
    pub fn new(config: &'b ServiceConfig, definition: ServiceDefinition) -> Self {
        Service { config, definition }
    }

    pub fn name(&self) -> &str {
        match self.definition.metadata.service_abbreviation {
            Some(ref service_abbreviation) => service_abbreviation.as_str(),
            None => self.definition.metadata.service_full_name.as_ref(),
        }
    }

    pub fn full_name(&self) -> &str {
        &self.definition.metadata.service_full_name
    }

    pub fn service_id(&self) -> Option<&str> {
        self.definition
            .metadata
            .service_id
            .as_ref()
            .map(std::string::String::as_str)
    }

    pub fn documentation(&self) -> Option<&String> {
        self.definition.documentation.as_ref()
    }

    pub fn protocol(&self) -> &str {
        &self.definition.metadata.protocol
    }

    pub fn client_type_name(&self) -> String {
        format!("{}Client", self.service_type_name())
    }

    pub fn service_type_name(&self) -> &str {
        &self.config.base_type_name
    }

    pub fn endpoint_prefix(&self) -> &str {
        &self.definition.metadata.endpoint_prefix
    }

    pub fn api_version(&self) -> &str {
        &self.definition.metadata.api_version
    }

    pub fn target_prefix(&self) -> Option<&String> {
        self.definition.metadata.target_prefix.as_ref()
    }

    pub fn json_version(&self) -> Option<&String> {
        self.definition.metadata.json_version.as_ref()
    }

    pub fn shapes(&self) -> &BTreeMap<String, Shape> {
        &self.definition.shapes
    }

    pub fn get_shape(&self, name: &str) -> Option<&Shape> {
        self.definition.shapes.get(name)
    }

    pub fn operations(&self) -> &BTreeMap<String, Operation> {
        &self.definition.operations
    }

    pub fn shape_for_value<'a>(&'a self, value: &Value) -> Option<&'a Shape> {
        self.definition.shapes.get(&value.shape)
    }

    pub fn shape_for_member<'a>(&'a self, member: &Member) -> Option<&'a Shape> {
        self.definition.shapes.get(&member.shape)
    }

    pub fn shape_type_for_member<'a>(&'a self, member: &Member) -> Option<ShapeType> {
        self.definition
            .shapes
            .get(&member.shape)
            .map(|shape| shape.shape_type)
    }

    pub fn signing_name(&self) -> String {
        match self.definition.metadata.signing_name {
            Some(ref signing_name) => signing_name.to_string(),
            None => self.definition.metadata.endpoint_prefix.to_string(),
        }
    }

    pub fn needs_serde_json_crate(&self) -> bool {
        match self.name() {
            "AmazonApiGatewayManagementApi"
            | "Amazon CloudSearch Domain"
            | "AWS Mobile"
            | "AWS IoT Data Plane"
            | "Amazon SageMaker Runtime"
            | "SSO" => false,
            _ => true,
        }
    }

    pub fn has_event_streams(&self) -> bool {
        self.shapes().values().into_iter().any(|s| s.eventstream())
    }

    pub fn get_dependencies(&self) -> BTreeMap<String, cargo::Dependency> {
        let mut dependencies = BTreeMap::new();

        dependencies.insert(
            "async-trait".to_owned(),
            cargo::Dependency::Simple("0.1".into()),
        );
        dependencies.insert("bytes".to_owned(), cargo::Dependency::Simple("1.0".into()));
        dependencies.insert(
            "futures".to_owned(),
            cargo::Dependency::Extended {
                path: None,
                version: Some("0.3".to_owned()),
                optional: None,
                default_features: None,
                features: None,
            },
        );
        dependencies.insert(

        dev_dependencies.insert("rusoto_mock".to_owned(), cargo::Dependency::Extended {
            path: Some("../../../mock".into()),
            version: Some("0.26.0".into()),
            optional: None,
            default_features: None,
            features: None
            },
        );

        match self.protocol() {
            "json" => {
                dependencies.insert(
                    "serde".to_owned(),
                    cargo::Dependency::Extended {
                        version: Some("1.0".into()),
                        path: None,
                        optional: None,
                        default_features: None,
                        features: Some(vec!["derive".into()]),
                    },
                );
                dependencies.insert(
                    "serde_json".to_owned(),
                    cargo::Dependency::Simple("1.0".into()),
                );
            }
            "query" | "ec2" => {
                dependencies.insert(
                    "serde".to_owned(),
                    cargo::Dependency::Extended {
                        version: Some("1.0.2".into()),
                        optional: Some(true),
                        path: None,
                        default_features: None,
                        features: None,
                    },
                );
                dependencies.insert(
                    "serde_derive".to_owned(),
                    cargo::Dependency::Extended {
                        version: Some("1.0.2".into()),
                        optional: Some(true),
                        path: None,
                        default_features: None,
                        features: None,
                    },
                );
                dependencies.insert(
                    "serde_urlencoded".to_owned(),
                    cargo::Dependency::Simple("0.7".into()),
                );
                dependencies.insert("xml-rs".to_owned(), cargo::Dependency::Simple("0.8".into()));
            }
            "rest-xml" => {
                dependencies.insert(
                    "serde".to_owned(),
                    cargo::Dependency::Extended {
                        version: Some("1.0.2".into()),
                        optional: Some(true),
                        path: None,
                        default_features: None,
                        features: None,
                    },
                );
                dependencies.insert(
                    "serde_derive".to_owned(),
                    cargo::Dependency::Extended {
                        version: Some("1.0.2".into()),
                        optional: Some(true),
                        path: None,
                        default_features: None,
                        features: None,
                    },
                );
                dependencies.insert("xml-rs".to_owned(), cargo::Dependency::Simple("0.8".into()));
            }
            "rest-json" => {
                dependencies.insert(
                    "serde".to_owned(),
                    cargo::Dependency::Simple("1.0.103".into()),
                );
                dependencies.insert(
                    "serde_derive".to_owned(),
                    cargo::Dependency::Simple("1.0.103".into()),
                );
                // some rest-json services don't use the `serde_json` crate:
                if self.needs_serde_json_crate() {
                    dependencies.insert(
                        "serde_json".to_owned(),
                        cargo::Dependency::Simple("1.0".into()),
                    );
                }
            }
            protocol => panic!("Unknown protocol {}", protocol),
        }

        if let Some(ref custom_dependencies) = self.config.custom_dependencies {
            dependencies.extend(custom_dependencies.clone());
        }

        dependencies
    }

    pub fn get_dev_dependencies(&self) -> BTreeMap<String, cargo::Dependency> {
        let mut dev_dependencies = BTreeMap::new();

        dev_dependencies.insert(
            "rusoto_mock".to_owned(),
            cargo::Dependency::Extended {
                path: Some("../../../mock".into()),
                version: Some(self.config.core_version.clone()),
                optional: None,
                default_features: Some(false),
                features: None,
            },
        );

        dev_dependencies.insert(
            "tokio".to_owned(),
            cargo::Dependency::Simple("1.0".to_owned()),
        );

        if let Some(ref custom_dev_dependencies) = self.config.custom_dev_dependencies {
            dev_dependencies.extend(custom_dev_dependencies.clone());
        }

        dev_dependencies
    }

    pub fn visit_shapes<F>(&self, shape_name: &str, visitor: &mut F)
    where
        F: FnMut(&str, &Shape) -> bool,
    {
        let shape = self
            .get_shape(shape_name)
            .expect("Shape missing from service definition");

        if !visitor(shape_name, shape) {
            return;
        }

        match shape.shape_type {
            ShapeType::Structure => {
                if let Some(ref members) = shape.members {
                    for member in members.values() {
                        self.visit_shapes(&member.shape, visitor);
                    }
                }
            }
            ShapeType::Map => {
                self.visit_shapes(shape.key_type(), visitor);
                self.visit_shapes(shape.value_type(), visitor);
            }
            ShapeType::List => {
                self.visit_shapes(shape.member_type(), visitor);
            }
            _ => {}
        }
    }
}

<MSG> Update version of rusoto_mock

<DFF> @@ -138,7 +138,7 @@ impl <'b> Service <'b> {
 
         dev_dependencies.insert("rusoto_mock".to_owned(), cargo::Dependency::Extended {
             path: Some("../../../mock".into()),
-            version: Some("0.26.0".into()),
+            version: Some("0.27.0".into()),
             optional: None,
             default_features: None,
             features: None

{'commit': 'diff --git a/service_crategen/src/service.rs b/service_crategen/src/service.rs\nindex 98259265f..48d26ea2d 100644\n--- a/service_crategen/src/service.rs\n+++ b/service_crategen/src/service.rs\n@@ -138,7 +138,7 @@ impl <\'b> Service <\'b> {\n \n         dev_dependencies.insert("rusoto_mock".to_owned(), cargo::Dependency::Extended {\n             path: Some("../../../mock".into()),\n-            version: Some("0.26.0".into()),\n+            version: Some("0.27.0".into()),\n             optional: None,\n             default_features: None,\n             features: None\n', 'commit_subject': 'Update version of rusoto_mock', 'repo_name': 'rusoto/rusoto', 'committer': {'name': 'Esty Thomas', 'email': '68ec15d2516a37fccb96d5b3fc9cc6315c27dd45@healpay.com', 'time_sec': '1534256533', 'tz_offset': '-240', 'date': {'seconds': '1534256533'}}, 'commit_tree': '5ca923d06ecd42d65bbc278e59b4b5cebb851b42', 'commit_message': 'Update version of rusoto_mock\n', 'language_name': 'Rust', 'license': 'mit', 'hunks': '@@ -138,7 +138,7 @@ impl <\'b> Service <\'b> {\n \n         dev_dependencies.insert("rusoto_mock".to_owned(), cargo::Dependency::Extended {\n             path: Some("../../../mock".into()),\n-            version: Some("0.26.0".into()),\n+            version: Some("0.27.0".into()),\n             optional: None,\n             default_features: None,\n             features: None\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/service_crategen/src/service.rs', 'tgt_file': 'b/service_crategen/src/service.rs', 'file_extension': '.rs', 'before_file': 'use std::collections::BTreeMap;\n\nuse crate::botocore::{Member, Operation, ServiceDefinition, Shape, ShapeType, Value};\nuse crate::cargo;\nuse crate::config::ServiceConfig;\n\n#[derive(Debug)]\npub struct Service<\'a> {\n    config: &\'a crate::ServiceConfig,\n    definition: ServiceDefinition,\n}\n\nimpl<\'b> Service<\'b> {\n    pub fn new(config: &\'b ServiceConfig, definition: ServiceDefinition) -> Self {\n        Service { config, definition }\n    }\n\n    pub fn name(&self) -> &str {\n        match self.definition.metadata.service_abbreviation {\n            Some(ref service_abbreviation) => service_abbreviation.as_str(),\n            None => self.definition.metadata.service_full_name.as_ref(),\n        }\n    }\n\n    pub fn full_name(&self) -> &str {\n        &self.definition.metadata.service_full_name\n    }\n\n    pub fn service_id(&self) -> Option<&str> {\n        self.definition\n            .metadata\n            .service_id\n            .as_ref()\n            .map(std::string::String::as_str)\n    }\n\n    pub fn documentation(&self) -> Option<&String> {\n        self.definition.documentation.as_ref()\n    }\n\n    pub fn protocol(&self) -> &str {\n        &self.definition.metadata.protocol\n    }\n\n    pub fn client_type_name(&self) -> String {\n        format!("{}Client", self.service_type_name())\n    }\n\n    pub fn service_type_name(&self) -> &str {\n        &self.config.base_type_name\n    }\n\n    pub fn endpoint_prefix(&self) -> &str {\n        &self.definition.metadata.endpoint_prefix\n    }\n\n    pub fn api_version(&self) -> &str {\n        &self.definition.metadata.api_version\n    }\n\n    pub fn target_prefix(&self) -> Option<&String> {\n        self.definition.metadata.target_prefix.as_ref()\n    }\n\n    pub fn json_version(&self) -> Option<&String> {\n        self.definition.metadata.json_version.as_ref()\n    }\n\n    pub fn shapes(&self) -> &BTreeMap<String, Shape> {\n        &self.definition.shapes\n    }\n\n    pub fn get_shape(&self, name: &str) -> Option<&Shape> {\n        self.definition.shapes.get(name)\n    }\n\n    pub fn operations(&self) -> &BTreeMap<String, Operation> {\n        &self.definition.operations\n    }\n\n    pub fn shape_for_value<\'a>(&\'a self, value: &Value) -> Option<&\'a Shape> {\n        self.definition.shapes.get(&value.shape)\n    }\n\n    pub fn shape_for_member<\'a>(&\'a self, member: &Member) -> Option<&\'a Shape> {\n        self.definition.shapes.get(&member.shape)\n    }\n\n    pub fn shape_type_for_member<\'a>(&\'a self, member: &Member) -> Option<ShapeType> {\n        self.definition\n            .shapes\n            .get(&member.shape)\n            .map(|shape| shape.shape_type)\n    }\n\n    pub fn signing_name(&self) -> String {\n        match self.definition.metadata.signing_name {\n            Some(ref signing_name) => signing_name.to_string(),\n            None => self.definition.metadata.endpoint_prefix.to_string(),\n        }\n    }\n\n    pub fn needs_serde_json_crate(&self) -> bool {\n        match self.name() {\n            "AmazonApiGatewayManagementApi"\n            | "Amazon CloudSearch Domain"\n            | "AWS Mobile"\n            | "AWS IoT Data Plane"\n            | "Amazon SageMaker Runtime"\n            | "SSO" => false,\n            _ => true,\n        }\n    }\n\n    pub fn has_event_streams(&self) -> bool {\n        self.shapes().values().into_iter().any(|s| s.eventstream())\n    }\n\n    pub fn get_dependencies(&self) -> BTreeMap<String, cargo::Dependency> {\n        let mut dependencies = BTreeMap::new();\n\n        dependencies.insert(\n            "async-trait".to_owned(),\n            cargo::Dependency::Simple("0.1".into()),\n        );\n        dependencies.insert("bytes".to_owned(), cargo::Dependency::Simple("1.0".into()));\n        dependencies.insert(\n            "futures".to_owned(),\n            cargo::Dependency::Extended {\n                path: None,\n                version: Some("0.3".to_owned()),\n                optional: None,\n                default_features: None,\n                features: None,\n            },\n        );\n        dependencies.insert(\n\n        dev_dependencies.insert("rusoto_mock".to_owned(), cargo::Dependency::Extended {\n            path: Some("../../../mock".into()),\n            version: Some("0.26.0".into()),\n            optional: None,\n            default_features: None,\n            features: None\n            },\n        );\n\n        match self.protocol() {\n            "json" => {\n                dependencies.insert(\n                    "serde".to_owned(),\n                    cargo::Dependency::Extended {\n                        version: Some("1.0".into()),\n                        path: None,\n                        optional: None,\n                        default_features: None,\n                        features: Some(vec!["derive".into()]),\n                    },\n                );\n                dependencies.insert(\n                    "serde_json".to_owned(),\n                    cargo::Dependency::Simple("1.0".into()),\n                );\n            }\n            "query" | "ec2" => {\n                dependencies.insert(\n                    "serde".to_owned(),\n                    cargo::Dependency::Extended {\n                        version: Some("1.0.2".into()),\n                        optional: Some(true),\n                        path: None,\n                        default_features: None,\n                        features: None,\n                    },\n                );\n                dependencies.insert(\n                    "serde_derive".to_owned(),\n                    cargo::Dependency::Extended {\n                        version: Some("1.0.2".into()),\n                        optional: Some(true),\n                        path: None,\n                        default_features: None,\n                        features: None,\n                    },\n                );\n                dependencies.insert(\n                    "serde_urlencoded".to_owned(),\n                    cargo::Dependency::Simple("0.7".into()),\n                );\n                dependencies.insert("xml-rs".to_owned(), cargo::Dependency::Simple("0.8".into()));\n            }\n            "rest-xml" => {\n                dependencies.insert(\n                    "serde".to_owned(),\n                    cargo::Dependency::Extended {\n                        version: Some("1.0.2".into()),\n                        optional: Some(true),\n                        path: None,\n                        default_features: None,\n                        features: None,\n                    },\n                );\n                dependencies.insert(\n                    "serde_derive".to_owned(),\n                    cargo::Dependency::Extended {\n                        version: Some("1.0.2".into()),\n                        optional: Some(true),\n                        path: None,\n                        default_features: None,\n                        features: None,\n                    },\n                );\n                dependencies.insert("xml-rs".to_owned(), cargo::Dependency::Simple("0.8".into()));\n            }\n            "rest-json" => {\n                dependencies.insert(\n                    "serde".to_owned(),\n                    cargo::Dependency::Simple("1.0.103".into()),\n                );\n                dependencies.insert(\n                    "serde_derive".to_owned(),\n                    cargo::Dependency::Simple("1.0.103".into()),\n                );\n                // some rest-json services don\'t use the `serde_json` crate:\n                if self.needs_serde_json_crate() {\n                    dependencies.insert(\n                        "serde_json".to_owned(),\n                        cargo::Dependency::Simple("1.0".into()),\n                    );\n                }\n            }\n            protocol => panic!("Unknown protocol {}", protocol),\n        }\n\n        if let Some(ref custom_dependencies) = self.config.custom_dependencies {\n            dependencies.extend(custom_dependencies.clone());\n        }\n\n        dependencies\n    }\n\n    pub fn get_dev_dependencies(&self) -> BTreeMap<String, cargo::Dependency> {\n        let mut dev_dependencies = BTreeMap::new();\n\n        dev_dependencies.insert(\n            "rusoto_mock".to_owned(),\n            cargo::Dependency::Extended {\n                path: Some("../../../mock".into()),\n                version: Some(self.config.core_version.clone()),\n                optional: None,\n                default_features: Some(false),\n                features: None,\n            },\n        );\n\n        dev_dependencies.insert(\n            "tokio".to_owned(),\n            cargo::Dependency::Simple("1.0".to_owned()),\n        );\n\n        if let Some(ref custom_dev_dependencies) = self.config.custom_dev_dependencies {\n            dev_dependencies.extend(custom_dev_dependencies.clone());\n        }\n\n        dev_dependencies\n    }\n\n    pub fn visit_shapes<F>(&self, shape_name: &str, visitor: &mut F)\n    where\n        F: FnMut(&str, &Shape) -> bool,\n    {\n        let shape = self\n            .get_shape(shape_name)\n            .expect("Shape missing from service definition");\n\n        if !visitor(shape_name, shape) {\n            return;\n        }\n\n        match shape.shape_type {\n            ShapeType::Structure => {\n                if let Some(ref members) = shape.members {\n                    for member in members.values() {\n                        self.visit_shapes(&member.shape, visitor);\n                    }\n                }\n            }\n            ShapeType::Map => {\n                self.visit_shapes(shape.key_type(), visitor);\n                self.visit_shapes(shape.value_type(), visitor);\n            }\n            ShapeType::List => {\n                self.visit_shapes(shape.member_type(), visitor);\n            }\n            _ => {}\n        }\n    }\n}\n', 'message': 'Update version of rusoto_mock\n', 'author_name': 'Esty Thomas', 'lang': 'rs'}