use std::error::Error;
use std::fmt;
#[allow(warnings)]
use futures::future;
use futures::Future;
use rusoto_core::credential::ProvideAwsCredentials;
use rusoto_core::region;
use rusoto_core::request::{BufferedHttpResponse, DispatchSignedRequest};
use rusoto_core::{Client, RusotoError, RusotoFuture};
use rusoto_core::param::{Params, ServiceParams};
use rusoto_core::proto;
use rusoto_core::signature::SignedRequest;
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct DeleteThingShadowRequest {
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct DeleteThingShadowResponse {
pub payload: bytes::Bytes,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct GetThingShadowRequest {
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct GetThingShadowResponse {
pub payload: Option<bytes::Bytes>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct PublishRequest {
#[serde(rename = "payload")]
#[serde(
deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
default
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub payload: Option<bytes::Bytes>,
#[serde(rename = "qos")]
#[serde(skip_serializing_if = "Option::is_none")]
pub qos: Option<i64>,
#[serde(rename = "topic")]
pub topic: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize)]
pub struct UpdateThingShadowRequest {
#[serde(rename = "payload")]
#[serde(
deserialize_with = "::rusoto_core::serialization::SerdeBlob::deserialize_blob",
serialize_with = "::rusoto_core::serialization::SerdeBlob::serialize_blob",
default
)]
pub payload: bytes::Bytes,
#[serde(rename = "thingName")]
pub thing_name: String,
}
#[derive(Default, Debug, Clone, PartialEq)]
pub struct UpdateThingShadowResponse {
pub payload: Option<bytes::Bytes>,
}
#[derive(Debug, PartialEq)]
pub enum DeleteThingShadowError {
InternalFailure(String),
InvalidRequest(String),
MethodNotAllowed(String),
ResourceNotFound(String),
ServiceUnavailable(String),
Throttling(String),
Unauthorized(String),
UnsupportedDocumentEncoding(String),
}
impl DeleteThingShadowError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<DeleteThingShadowError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"InternalFailureException" => {
return RusotoError::Service(DeleteThingShadowError::InternalFailure(err.msg))
}
"InvalidRequestException" => {
return RusotoError::Service(DeleteThingShadowError::InvalidRequest(err.msg))
}
"MethodNotAllowedException" => {
return RusotoError::Service(DeleteThingShadowError::MethodNotAllowed(err.msg))
}
"ResourceNotFoundException" => {
return RusotoError::Service(DeleteThingShadowError::ResourceNotFound(err.msg))
}
"ServiceUnavailableException" => {
return RusotoError::Service(DeleteThingShadowError::ServiceUnavailable(
err.msg,
))
}
"ThrottlingException" => {
return RusotoError::Service(DeleteThingShadowError::Throttling(err.msg))
}
"UnauthorizedException" => {
return RusotoError::Service(DeleteThingShadowError::Unauthorized(err.msg))
}
"UnsupportedDocumentEncodingException" => {
return RusotoError::Service(
DeleteThingShadowError::UnsupportedDocumentEncoding(err.msg),
)
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for DeleteThingShadowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for DeleteThingShadowError {
fn description(&self) -> &str {
match *self {
DeleteThingShadowError::InternalFailure(ref cause) => cause,
DeleteThingShadowError::InvalidRequest(ref cause) => cause,
DeleteThingShadowError::MethodNotAllowed(ref cause) => cause,
DeleteThingShadowError::ResourceNotFound(ref cause) => cause,
DeleteThingShadowError::ServiceUnavailable(ref cause) => cause,
DeleteThingShadowError::Throttling(ref cause) => cause,
DeleteThingShadowError::Unauthorized(ref cause) => cause,
DeleteThingShadowError::UnsupportedDocumentEncoding(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum GetThingShadowError {
InternalFailure(String),
InvalidRequest(String),
MethodNotAllowed(String),
ResourceNotFound(String),
ServiceUnavailable(String),
Throttling(String),
Unauthorized(String),
UnsupportedDocumentEncoding(String),
}
impl GetThingShadowError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<GetThingShadowError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"InternalFailureException" => {
return RusotoError::Service(GetThingShadowError::InternalFailure(err.msg))
}
"InvalidRequestException" => {
return RusotoError::Service(GetThingShadowError::InvalidRequest(err.msg))
}
"MethodNotAllowedException" => {
return RusotoError::Service(GetThingShadowError::MethodNotAllowed(err.msg))
}
"ResourceNotFoundException" => {
return RusotoError::Service(GetThingShadowError::ResourceNotFound(err.msg))
}
"ServiceUnavailableException" => {
return RusotoError::Service(GetThingShadowError::ServiceUnavailable(err.msg))
}
"ThrottlingException" => {
return RusotoError::Service(GetThingShadowError::Throttling(err.msg))
}
"UnauthorizedException" => {
return RusotoError::Service(GetThingShadowError::Unauthorized(err.msg))
}
"UnsupportedDocumentEncodingException" => {
return RusotoError::Service(GetThingShadowError::UnsupportedDocumentEncoding(
err.msg,
))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for GetThingShadowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for GetThingShadowError {
fn description(&self) -> &str {
match *self {
GetThingShadowError::InternalFailure(ref cause) => cause,
GetThingShadowError::InvalidRequest(ref cause) => cause,
GetThingShadowError::MethodNotAllowed(ref cause) => cause,
GetThingShadowError::ResourceNotFound(ref cause) => cause,
GetThingShadowError::ServiceUnavailable(ref cause) => cause,
GetThingShadowError::Throttling(ref cause) => cause,
GetThingShadowError::Unauthorized(ref cause) => cause,
GetThingShadowError::UnsupportedDocumentEncoding(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum PublishError {
InternalFailure(String),
InvalidRequest(String),
MethodNotAllowed(String),
Unauthorized(String),
}
impl PublishError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<PublishError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"InternalFailureException" => {
return RusotoError::Service(PublishError::InternalFailure(err.msg))
}
"InvalidRequestException" => {
return RusotoError::Service(PublishError::InvalidRequest(err.msg))
}
"MethodNotAllowedException" => {
return RusotoError::Service(PublishError::MethodNotAllowed(err.msg))
}
"UnauthorizedException" => {
return RusotoError::Service(PublishError::Unauthorized(err.msg))
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for PublishError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for PublishError {
fn description(&self) -> &str {
match *self {
PublishError::InternalFailure(ref cause) => cause,
PublishError::InvalidRequest(ref cause) => cause,
PublishError::MethodNotAllowed(ref cause) => cause,
PublishError::Unauthorized(ref cause) => cause,
}
}
}
#[derive(Debug, PartialEq)]
pub enum UpdateThingShadowError {
Conflict(String),
InternalFailure(String),
InvalidRequest(String),
MethodNotAllowed(String),
RequestEntityTooLarge(String),
ServiceUnavailable(String),
Throttling(String),
Unauthorized(String),
UnsupportedDocumentEncoding(String),
}
impl UpdateThingShadowError {
pub fn from_response(res: BufferedHttpResponse) -> RusotoError<UpdateThingShadowError> {
if let Some(err) = proto::json::Error::parse_rest(&res) {
match err.typ.as_str() {
"ConflictException" => {
return RusotoError::Service(UpdateThingShadowError::Conflict(err.msg))
}
"InternalFailureException" => {
return RusotoError::Service(UpdateThingShadowError::InternalFailure(err.msg))
}
"InvalidRequestException" => {
return RusotoError::Service(UpdateThingShadowError::InvalidRequest(err.msg))
}
"MethodNotAllowedException" => {
return RusotoError::Service(UpdateThingShadowError::MethodNotAllowed(err.msg))
}
"RequestEntityTooLargeException" => {
return RusotoError::Service(UpdateThingShadowError::RequestEntityTooLarge(
err.msg,
))
}
"ServiceUnavailableException" => {
return RusotoError::Service(UpdateThingShadowError::ServiceUnavailable(
err.msg,
))
}
"ThrottlingException" => {
return RusotoError::Service(UpdateThingShadowError::Throttling(err.msg))
}
"UnauthorizedException" => {
return RusotoError::Service(UpdateThingShadowError::Unauthorized(err.msg))
}
"UnsupportedDocumentEncodingException" => {
return RusotoError::Service(
UpdateThingShadowError::UnsupportedDocumentEncoding(err.msg),
)
}
"ValidationException" => return RusotoError::Validation(err.msg),
_ => {}
}
}
return RusotoError::Unknown(res);
}
}
impl fmt::Display for UpdateThingShadowError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for UpdateThingShadowError {
fn description(&self) -> &str {
match *self {
UpdateThingShadowError::Conflict(ref cause) => cause,
UpdateThingShadowError::InternalFailure(ref cause) => cause,
UpdateThingShadowError::InvalidRequest(ref cause) => cause,
UpdateThingShadowError::MethodNotAllowed(ref cause) => cause,
UpdateThingShadowError::RequestEntityTooLarge(ref cause) => cause,
UpdateThingShadowError::ServiceUnavailable(ref cause) => cause,
UpdateThingShadowError::Throttling(ref cause) => cause,
UpdateThingShadowError::Unauthorized(ref cause) => cause,
UpdateThingShadowError::UnsupportedDocumentEncoding(ref cause) => cause,
}
}
}
pub trait IotData {
fn delete_thing_shadow(
&self,
input: DeleteThingShadowRequest,
) -> RusotoFuture<DeleteThingShadowResponse, DeleteThingShadowError>;
fn get_thing_shadow(
&self,
input: GetThingShadowRequest,
) -> RusotoFuture<GetThingShadowResponse, GetThingShadowError>;
fn publish(&self, input: PublishRequest) -> RusotoFuture<(), PublishError>;
fn update_thing_shadow(
&self,
input: UpdateThingShadowRequest,
) -> RusotoFuture<UpdateThingShadowResponse, UpdateThingShadowError>;
}
#[derive(Clone)]
pub struct IotDataClient {
client: Client,
region: region::Region,
}
impl IotDataClient {
pub fn new(region: region::Region) -> IotDataClient {
IotDataClient {
client: Client::shared(),
region,
}
}
pub fn new_with<P, D>(
request_dispatcher: D,
credentials_provider: P,
region: region::Region,
) -> IotDataClient
where
P: ProvideAwsCredentials + Send + Sync + 'static,
P::Future: Send,
D: DispatchSignedRequest + Send + Sync + 'static,
D::Future: Send,
{
IotDataClient {
client: Client::new_with(credentials_provider, request_dispatcher),
region,
}
}
}
impl IotData for IotDataClient {
fn delete_thing_shadow(
&self,
input: DeleteThingShadowRequest,
) -> RusotoFuture<DeleteThingShadowResponse, DeleteThingShadowError> {
let request_uri = format!("/things/{thing_name}/shadow", thing_name = input.thing_name);
let mut request = SignedRequest::new("DELETE", "iotdata", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.iot".to_string());
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let mut result = DeleteThingShadowResponse::default();
result.payload = response.body;
Ok(result)
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(DeleteThingShadowError::from_response(response))),
)
}
})
}
fn get_thing_shadow(
&self,
input: GetThingShadowRequest,
) -> RusotoFuture<GetThingShadowResponse, GetThingShadowError> {
let request_uri = format!("/things/{thing_name}/shadow", thing_name = input.thing_name);
let mut request = SignedRequest::new("GET", "iotdata", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.iot".to_string());
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let mut result = GetThingShadowResponse::default();
result.payload = Some(response.body);
Ok(result)
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(GetThingShadowError::from_response(response))),
)
}
})
}
fn publish(&self, input: PublishRequest) -> RusotoFuture<(), PublishError> {
let request_uri = format!("/topics/{topic}", topic = input.topic);
let mut request = SignedRequest::new("POST", "iotdata", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.iot".to_string());
let encoded = if let Some(ref payload) = input.payload {
Some(payload.to_owned())
} else {
None
};
request.set_payload(encoded);
let mut params = Params::new();
if let Some(ref x) = input.qos {
params.put("qos", x);
}
request.set_params(params);
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let result = ::std::mem::drop(response);
Ok(result)
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(PublishError::from_response(response))),
)
}
})
}
fn update_thing_shadow(
&self,
input: UpdateThingShadowRequest,
) -> RusotoFuture<UpdateThingShadowResponse, UpdateThingShadowError> {
let request_uri = format!("/things/{thing_name}/shadow", thing_name = input.thing_name);
let mut request = SignedRequest::new("POST", "iotdata", &self.region, &request_uri);
request.set_content_type("application/x-amz-json-1.1".to_owned());
request.set_endpoint_prefix("data.iot".to_string());
let encoded = Some(input.payload.to_owned());
request.set_payload(encoded);
self.client.sign_and_dispatch(request, |response| {
if response.status.is_success() {
Box::new(response.buffer().from_err().and_then(|response| {
let mut result = UpdateThingShadowResponse::default();
result.payload = Some(response.body);
Ok(result)
}))
} else {
Box::new(
response
.buffer()
.from_err()
.and_then(|response| Err(UpdateThingShadowError::from_response(response))),
)
}
})
}
}