From 535747f06b5742f1ab3105ab80c3dbccf6bca415 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 10:37:58 +0100 Subject: [PATCH 01/13] Add nightly only into_future feature --- sdk/data_cosmos/Cargo.toml | 1 + sdk/data_cosmos/src/lib.rs | 1 + sdk/data_cosmos/src/operations/create_database.rs | 10 +++++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sdk/data_cosmos/Cargo.toml b/sdk/data_cosmos/Cargo.toml index 58bb51bffe..08bb6d1f07 100644 --- a/sdk/data_cosmos/Cargo.toml +++ b/sdk/data_cosmos/Cargo.toml @@ -43,3 +43,4 @@ stop-token = { version = "0.7.0", features = ["tokio"] } [features] test_e2e = [] mock_transport_framework = [ "azure_core/mock_transport_framework"] +into_future = [] diff --git a/sdk/data_cosmos/src/lib.rs b/sdk/data_cosmos/src/lib.rs index 0fc8cfc9b2..201ae4d2ae 100644 --- a/sdk/data_cosmos/src/lib.rs +++ b/sdk/data_cosmos/src/lib.rs @@ -1,6 +1,7 @@ #![allow(clippy::enum_variant_names)] #![allow(clippy::new_without_default)] #![allow(clippy::module_inception)] +#![cfg_attr(feature = "into_future", feature(into_future))] /*! # The Cosmos DB crate. diff --git a/sdk/data_cosmos/src/operations/create_database.rs b/sdk/data_cosmos/src/operations/create_database.rs index e5acae9a77..31f06b0157 100644 --- a/sdk/data_cosmos/src/operations/create_database.rs +++ b/sdk/data_cosmos/src/operations/create_database.rs @@ -64,7 +64,15 @@ impl CreateDatabaseBuilder { } } -/// A future of a create database response +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for CreateDatabaseBuilder { + type Future = CreateDatabase; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) + } +} + type CreateDatabase = futures::future::BoxFuture<'static, azure_core::error::Result>; From e454b62a45e5b7b3191dc99256351f7637563f9f Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 11:22:40 +0100 Subject: [PATCH 02/13] CreateCollectionBuilder::into_future --- .../examples/create_delete_database.rs | 8 +-- sdk/data_cosmos/examples/document_00.rs | 7 +- .../src/clients/database_client.rs | 23 ++---- .../src/operations/create_collection.rs | 72 ++++++++++++++----- 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/sdk/data_cosmos/examples/create_delete_database.rs b/sdk/data_cosmos/examples/create_delete_database.rs index dae6703d9a..147531f8d0 100644 --- a/sdk/data_cosmos/examples/create_delete_database.rs +++ b/sdk/data_cosmos/examples/create_delete_database.rs @@ -46,13 +46,9 @@ async fn main() -> Result<(), Box> { // create collection! { let db_client = client.clone().into_database_client(database_name.clone()); - let create_collection_response = db_client - .create_collection( - Context::new(), - "panzadoro", - CreateCollectionOptions::new("/id"), - ) + .create_collection("panzadoro", "/id") + .into_future() .await?; println!( diff --git a/sdk/data_cosmos/examples/document_00.rs b/sdk/data_cosmos/examples/document_00.rs index 3e4a454cfb..9644da60e8 100644 --- a/sdk/data_cosmos/examples/document_00.rs +++ b/sdk/data_cosmos/examples/document_00.rs @@ -102,11 +102,8 @@ async fn main() -> Result<(), Box> { client .clone() .into_database_client(database.id.clone()) - .create_collection( - Context::new(), - COLLECTION, - CreateCollectionOptions::new("/id"), - ) + .create_collection(COLLECTION, "/id") + .into_future() .await? .collection } diff --git a/sdk/data_cosmos/src/clients/database_client.rs b/sdk/data_cosmos/src/clients/database_client.rs index dae0e76308..3581421dfe 100644 --- a/sdk/data_cosmos/src/clients/database_client.rs +++ b/sdk/data_cosmos/src/clients/database_client.rs @@ -1,5 +1,6 @@ use super::*; use crate::operations::*; +use crate::resources::collection::PartitionKey; use crate::resources::ResourceType; use crate::ReadonlyString; use azure_core::prelude::Continuation; @@ -154,24 +155,12 @@ impl DatabaseClient { } /// Create a collection - pub async fn create_collection>( + pub fn create_collection, P: Into>( &self, - ctx: Context, collection_name: S, - options: CreateCollectionOptions, - ) -> crate::Result { - let mut request = self.cosmos_client().prepare_request_pipeline( - &format!("dbs/{}/colls", self.database_name()), - http::Method::POST, - ); - - options.decorate_request(&mut request, collection_name.as_ref())?; - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Collections), &mut request) - .await?; - - Ok(CreateCollectionResponse::try_from(response).await?) + partition_key: P, + ) -> CreateCollectionBuilder { + CreateCollectionBuilder::new(self.clone(), collection_name.into(), partition_key.into()) } /// List users @@ -245,7 +234,7 @@ impl DatabaseClient { UserClient::new(self, user_name) } - fn pipeline(&self) -> &Pipeline { + pub(crate) fn pipeline(&self) -> &Pipeline { self.cosmos_client.pipeline() } } diff --git a/sdk/data_cosmos/src/operations/create_collection.rs b/sdk/data_cosmos/src/operations/create_collection.rs index 391dd62ad0..170ffbf62c 100644 --- a/sdk/data_cosmos/src/operations/create_collection.rs +++ b/sdk/data_cosmos/src/operations/create_collection.rs @@ -2,24 +2,34 @@ use crate::headers::from_headers::*; use crate::prelude::*; use crate::resources::collection::{IndexingPolicy, PartitionKey}; use azure_core::headers::{etag_from_headers, session_token_from_headers}; -use azure_core::{collect_pinned_stream, Request as HttpRequest, Response as HttpResponse}; +use azure_core::{collect_pinned_stream, Context, Response as HttpResponse}; use chrono::{DateTime, Utc}; #[derive(Debug, Clone)] -pub struct CreateCollectionOptions { +pub struct CreateCollectionBuilder { + client: DatabaseClient, partition_key: PartitionKey, consistency_level: Option, indexing_policy: Option, + collection_name: String, offer: Option, + context: Context, } -impl CreateCollectionOptions { - pub fn new>(partition_key: P) -> Self { +impl CreateCollectionBuilder { + pub(crate) fn new( + client: DatabaseClient, + collection_name: String, + partition_key: PartitionKey, + ) -> Self { Self { - partition_key: partition_key.into(), + client, + collection_name, + partition_key, consistency_level: None, indexing_policy: None, offer: None, + context: Context::new(), } } @@ -29,25 +39,49 @@ impl CreateCollectionOptions { offer: Offer => Some(offer), } - pub(crate) fn decorate_request( - &self, - request: &mut HttpRequest, - collection_name: &str, - ) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.offer, request)?; - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; + pub fn into_future(self) -> CreateCollection { + Box::pin(async move { + let mut request = self.client.cosmos_client().prepare_request_pipeline( + &format!("dbs/{}/colls", self.client.database_name()), + http::Method::POST, + ); + azure_core::headers::add_optional_header2(&self.offer, &mut request)?; + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; - let collection = CreateCollectionBody { - id: collection_name, - indexing_policy: &self.indexing_policy, - partition_key: &self.partition_key, - }; + let collection = CreateCollectionBody { + id: &self.collection_name, + indexing_policy: &self.indexing_policy, + partition_key: &self.partition_key, + }; - request.set_body(bytes::Bytes::from(serde_json::to_string(&collection)?).into()); - Ok(()) + request.set_body(bytes::Bytes::from(serde_json::to_string(&collection)?).into()); + + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Collections), + &mut request, + ) + .await?; + + Ok(CreateCollectionResponse::try_from(response).await?) + }) } } +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for CreateCollectionBuilder { + type Future = CreateCollection; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) + } +} + +type CreateCollection = + futures::future::BoxFuture<'static, crate::Result>; + /// Body for the create collection request #[derive(Serialize, Debug)] struct CreateCollectionBody<'a> { From 30e58ba3a5eb272f2396078362a2cff7942373ae Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 12:22:10 +0100 Subject: [PATCH 03/13] CreateDocument::into_future --- sdk/data_cosmos/examples/attachments_00.rs | 32 ++++----- sdk/data_cosmos/examples/database_00.rs | 9 ++- sdk/data_cosmos/examples/document_00.rs | 22 +++---- .../examples/document_entries_00.rs | 32 ++++----- .../examples/document_entries_01.rs | 27 ++++---- sdk/data_cosmos/examples/readme.rs | 25 ++++--- .../examples/user_permission_token.rs | 24 +++---- .../src/clients/collection_client.rs | 20 ++---- sdk/data_cosmos/src/cosmos_entity.rs | 14 ++-- .../src/operations/create_document.rs | 66 +++++++++++-------- sdk/data_cosmos/tests/cosmos_document.rs | 2 +- 11 files changed, 121 insertions(+), 152 deletions(-) diff --git a/sdk/data_cosmos/examples/attachments_00.rs b/sdk/data_cosmos/examples/attachments_00.rs index feebd12575..7251304ef3 100644 --- a/sdk/data_cosmos/examples/attachments_00.rs +++ b/sdk/data_cosmos/examples/attachments_00.rs @@ -1,28 +1,21 @@ -use azure_core::Context; use azure_data_cosmos::prelude::*; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; use std::error::Error; -// Now we create a sample struct. The Cow trick -// allows us to use the same struct for serializing -// (without having to own the items if not needed) and -// for deserializing (where owning is required). -// We do not need to define the "id" field here, it will be -// specified in the Document struct below. +// Now we create a sample struct. #[derive(Serialize, Deserialize, Clone, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone().into() } } @@ -50,17 +43,14 @@ async fn main() -> Result<(), Box> { let id = format!("unique_id{}", 100); let doc = MySampleStruct { - id: Cow::Borrowed(&id), - a_string: Cow::Borrowed("Something here"), + id, + a_string: "Something here".into(), a_number: 100, a_timestamp: chrono::Utc::now().timestamp(), }; // let's add an entity. - match client - .create_document(Context::new(), &doc, CreateDocumentOptions::new()) - .await - { + match client.create_document(doc.clone()).into_future().await { Ok(_) => { println!("document created"); } diff --git a/sdk/data_cosmos/examples/database_00.rs b/sdk/data_cosmos/examples/database_00.rs index df07b52155..5f0d0c41cb 100644 --- a/sdk/data_cosmos/examples/database_00.rs +++ b/sdk/data_cosmos/examples/database_00.rs @@ -49,12 +49,11 @@ async fn main() -> Result<(), Box> { }"#; let document: Value = serde_json::from_str(data)?; - let options = CreateDocumentOptions::new() - .is_upsert(true) - .partition_key(&43u32) - .unwrap(); let resp = collection_client - .create_document(Context::new(), &document, options) + .create_document(document) + .is_upsert(true) + .partition_key(&43u32)? + .into_future() .await?; println!("resp == {:?}", resp); diff --git a/sdk/data_cosmos/examples/document_00.rs b/sdk/data_cosmos/examples/document_00.rs index 9644da60e8..b446eb8d93 100644 --- a/sdk/data_cosmos/examples/document_00.rs +++ b/sdk/data_cosmos/examples/document_00.rs @@ -4,22 +4,21 @@ use serde::{Deserialize, Serialize}; // DB. use azure_core::prelude::*; use azure_data_cosmos::prelude::*; -use std::borrow::Cow; use std::error::Error; #[derive(Clone, Serialize, Deserialize, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -115,8 +114,8 @@ async fn main() -> Result<(), Box> { // data in them. Let's create a Document. The only constraint // is that we need an id and an arbitrary, Serializable type. let doc = MySampleStruct { - id: Cow::Owned("unique_id100".to_owned()), - a_string: Cow::Borrowed("Something here"), + id: "unique_id100".into(), + a_string: "Something here".into(), a_number: 100, a_timestamp: chrono::Utc::now().timestamp(), }; @@ -132,7 +131,8 @@ async fn main() -> Result<(), Box> { // the document attributes. let create_document_response = collection_client - .create_document(Context::new(), &doc, CreateDocumentOptions::new()) + .create_document(doc.clone()) + .into_future() .await?; println!( "create_document_response == {:#?}", diff --git a/sdk/data_cosmos/examples/document_entries_00.rs b/sdk/data_cosmos/examples/document_entries_00.rs index fb6fb8dd78..e18f404780 100644 --- a/sdk/data_cosmos/examples/document_entries_00.rs +++ b/sdk/data_cosmos/examples/document_entries_00.rs @@ -2,28 +2,22 @@ use azure_core::prelude::*; use azure_data_cosmos::prelude::*; use futures::stream::StreamExt; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; use std::error::Error; -// Now we create a sample struct. The Cow trick -// allows us to use the same struct for serializing -// (without having to own the items if not needed) and -// for deserializing (where owning is required). -// We do not need to define the "id" field here, it will be -// specified in the Document struct below. +// Now we create a sample struct. #[derive(Serialize, Deserialize, Clone, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -51,18 +45,14 @@ async fn main() -> Result<(), Box> { let mut response = None; for i in 0u64..5 { let doc = MySampleStruct { - id: Cow::Owned(format!("unique_id{}", i)), - a_string: Cow::Borrowed("Something here"), + id: format!("unique_id{}", i), + a_string: "Something here".into(), a_number: i, a_timestamp: chrono::Utc::now().timestamp(), }; // let's add an entity. - response = Some( - client - .create_document(Context::new(), &doc, CreateDocumentOptions::new()) - .await?, - ); + response = Some(client.create_document(doc.clone()).into_future().await?); } println!("Created 5 documents."); diff --git a/sdk/data_cosmos/examples/document_entries_01.rs b/sdk/data_cosmos/examples/document_entries_01.rs index 07f5416494..50beb3c505 100644 --- a/sdk/data_cosmos/examples/document_entries_01.rs +++ b/sdk/data_cosmos/examples/document_entries_01.rs @@ -1,22 +1,21 @@ use azure_core::Context; use azure_data_cosmos::prelude::*; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; use std::error::Error; #[derive(Serialize, Deserialize, Clone, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -42,19 +41,17 @@ async fn main() -> Result<(), Box> { let client = client.into_collection_client(collection_name); let mut doc = MySampleStruct { - id: Cow::Owned(format!("unique_id{}", 500)), - a_string: Cow::Borrowed("Something here"), + id: format!("unique_id{}", 500), + a_string: "Something here".into(), a_number: 600, a_timestamp: chrono::Utc::now().timestamp(), }; // let's add an entity. let create_document_response = client - .create_document( - Context::new(), - &doc, - CreateDocumentOptions::new().is_upsert(true), - ) + .create_document(doc.clone()) + .is_upsert(true) + .into_future() .await?; println!( diff --git a/sdk/data_cosmos/examples/readme.rs b/sdk/data_cosmos/examples/readme.rs index d8e1baf3fe..b90464e18c 100644 --- a/sdk/data_cosmos/examples/readme.rs +++ b/sdk/data_cosmos/examples/readme.rs @@ -3,25 +3,24 @@ use serde::{Deserialize, Serialize}; // Using the prelude module of the Cosmos crate makes easier to use the Rust Azure SDK for Cosmos. use azure_data_cosmos::prelude::*; use futures::stream::StreamExt; -use std::borrow::Cow; use std::error::Error; // This is the stuct we want to use in our sample. // Make sure to have a collection with partition key "a_number" for this example to // work (you can create with this SDK too, check the examples folder for that task). -#[derive(Serialize, Deserialize, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +#[derive(Serialize, Deserialize, Debug, Clone)] +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } // Here we mark "a_number" as partition key. -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { +impl azure_data_cosmos::CosmosEntity for MySampleStruct { type Entity = u64; - fn partition_key(&'a self) -> Self::Entity { + fn partition_key(&self) -> Self::Entity { self.a_number } } @@ -71,8 +70,8 @@ async fn main() -> Result<(), Box> { for i in 0..10 { // define the document. let document_to_insert = MySampleStruct { - id: Cow::Owned(format!("unique_id{}", i)), - a_string: Cow::Borrowed("Something here"), + id: format!("unique_id{}", i), + a_string: "Something here".into(), a_number: i * 100, // this is the partition key a_timestamp: chrono::Utc::now().timestamp(), }; @@ -80,11 +79,9 @@ async fn main() -> Result<(), Box> { // insert it and store the returned session token for later use! session_token = Some( collection_client - .create_document( - Context::new(), - &document_to_insert, - CreateDocumentOptions::new().is_upsert(true), - ) + .create_document(document_to_insert.clone()) + .is_upsert(true) + .into_future() .await? .session_token, // get only the session token, if everything else was ok! ); diff --git a/sdk/data_cosmos/examples/user_permission_token.rs b/sdk/data_cosmos/examples/user_permission_token.rs index 91ece86d5c..413dd03d31 100644 --- a/sdk/data_cosmos/examples/user_permission_token.rs +++ b/sdk/data_cosmos/examples/user_permission_token.rs @@ -120,14 +120,10 @@ async fn main() -> Result<(), Box> { .clone() .into_database_client(database_name.clone()) .into_collection_client(collection_name.clone()) - .create_document( - Context::new(), - &document, - CreateDocumentOptions::new() - .is_upsert(true) - .partition_key(&"Gianluigi Bombatomica") - .unwrap(), - ) + .create_document(document.clone()) + .is_upsert(true) + .partition_key(&"Gianluigi Bombatomica")? + .into_future() .await { Ok(_) => panic!("this should not happen!"), @@ -169,14 +165,10 @@ async fn main() -> Result<(), Box> { let create_document_response = client .into_database_client(database_name) .into_collection_client(collection_name) - .create_document( - Context::new(), - &document, - CreateDocumentOptions::new() - .is_upsert(true) - .partition_key(&"Gianluigi Bombatomica") - .unwrap(), - ) + .create_document(document) + .is_upsert(true) + .partition_key(&"Gianluigi Bombatomica")? + .into_future() .await?; println!( "create_document_response == {:#?}", diff --git a/sdk/data_cosmos/src/clients/collection_client.rs b/sdk/data_cosmos/src/clients/collection_client.rs index 1173e6b55b..ca33ad49ae 100644 --- a/sdk/data_cosmos/src/clients/collection_client.rs +++ b/sdk/data_cosmos/src/clients/collection_client.rs @@ -101,21 +101,11 @@ impl CollectionClient { } /// create a document in a collection - pub async fn create_document<'a, D: Serialize + CosmosEntity<'a>>( + pub fn create_document( &self, - ctx: Context, - document: &'a D, - options: CreateDocumentOptions, - ) -> crate::Result { - let mut request = self.prepare_doc_request_pipeline(http::Method::POST); - - options.decorate_request(&mut request, document)?; - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Documents), &mut request) - .await?; - - Ok(CreateDocumentResponse::try_from(response).await?) + document: D, + ) -> CreateDocumentBuilder { + CreateDocumentBuilder::new(self.clone(), document) } /// query documents in a collection @@ -191,7 +181,7 @@ impl CollectionClient { self.cosmos_client().pipeline() } - fn prepare_doc_request_pipeline(&self, http_method: http::Method) -> Request { + pub(crate) fn prepare_doc_request_pipeline(&self, http_method: http::Method) -> Request { let path = &format!( "dbs/{}/colls/{}/docs", self.database_client().database_name(), diff --git a/sdk/data_cosmos/src/cosmos_entity.rs b/sdk/data_cosmos/src/cosmos_entity.rs index 71f85ff329..6544cac9d0 100644 --- a/sdk/data_cosmos/src/cosmos_entity.rs +++ b/sdk/data_cosmos/src/cosmos_entity.rs @@ -4,18 +4,18 @@ use http::request::Builder; use serde::Serialize; /// CosmosDB partition key. Every CosmosDB entity must implement it. -pub trait CosmosEntity<'a> { +pub trait CosmosEntity { /// Returned type. - type Entity: Serialize + 'a; + type Entity: Serialize; /// Return partition key value as reference. - fn partition_key(&'a self) -> Self::Entity; + fn partition_key(&self) -> Self::Entity; } -impl<'a> CosmosEntity<'a> for serde_json::Value { - type Entity = &'a Self; - fn partition_key(&'a self) -> Self::Entity { - self +impl CosmosEntity for serde_json::Value { + type Entity = Self; + fn partition_key(&self) -> Self::Entity { + self.clone() } } diff --git a/sdk/data_cosmos/src/operations/create_document.rs b/sdk/data_cosmos/src/operations/create_document.rs index c1de59afaa..62e3e8cd9b 100644 --- a/sdk/data_cosmos/src/operations/create_document.rs +++ b/sdk/data_cosmos/src/operations/create_document.rs @@ -10,10 +10,11 @@ use http::StatusCode; use serde::Serialize; use std::convert::TryFrom; -use azure_core::{collect_pinned_stream, Request as HttpRequest, Response as HttpResponse}; +use azure_core::{collect_pinned_stream, Response as HttpResponse}; #[derive(Debug, Clone)] -pub struct CreateDocumentOptions { +pub struct CreateDocumentBuilder { + client: CollectionClient, is_upsert: IsUpsert, indexing_directive: IndexingDirective, if_match_condition: Option, @@ -21,11 +22,14 @@ pub struct CreateDocumentOptions { consistency_level: Option, allow_tentative_writes: TentativeWritesAllowance, partition_key: Option, + document: D, + context: Context, } -impl CreateDocumentOptions { - pub fn new() -> Self { +impl CreateDocumentBuilder { + pub(crate) fn new(client: CollectionClient, document: D) -> Self { Self { + client, is_upsert: IsUpsert::No, indexing_directive: IndexingDirective::Default, if_match_condition: None, @@ -33,6 +37,8 @@ impl CreateDocumentOptions { consistency_level: None, allow_tentative_writes: TentativeWritesAllowance::Deny, partition_key: None, + document, + context: Context::new(), } } @@ -53,33 +59,41 @@ impl CreateDocumentOptions { Ok(self) } - pub(crate) fn decorate_request<'b, DOC>( - &self, - req: &mut HttpRequest, - document: &'b DOC, - ) -> crate::Result<()> - where - DOC: Serialize + CosmosEntity<'b>, - { - let serialized = serde_json::to_string(document)?; - let partition_key = match &self.partition_key { - Some(s) => s.clone(), - None => serialize_partition_key(&document.partition_key())?, - }; + pub fn into_future(self) -> CreateDocument { + Box::pin(async move { + let document = self.document; + let serialized = serde_json::to_string(&document)?; + let partition_key = match self.partition_key { + Some(s) => s, + None => serialize_partition_key(&document.partition_key())?, + }; + let mut request = self.client.prepare_doc_request_pipeline(http::Method::POST); - add_as_partition_key_header_serialized2(&partition_key, req); - azure_core::headers::add_optional_header2(&self.if_match_condition, req)?; - azure_core::headers::add_optional_header2(&self.if_modified_since, req)?; - azure_core::headers::add_optional_header2(&self.consistency_level, req)?; - azure_core::headers::add_mandatory_header2(&self.is_upsert, req)?; - azure_core::headers::add_mandatory_header2(&self.indexing_directive, req)?; - azure_core::headers::add_mandatory_header2(&self.allow_tentative_writes, req)?; + add_as_partition_key_header_serialized2(&partition_key, &mut request); + azure_core::headers::add_optional_header2(&self.if_match_condition, &mut request)?; + azure_core::headers::add_optional_header2(&self.if_modified_since, &mut request)?; + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + azure_core::headers::add_mandatory_header2(&self.is_upsert, &mut request)?; + azure_core::headers::add_mandatory_header2(&self.indexing_directive, &mut request)?; + azure_core::headers::add_mandatory_header2(&self.allow_tentative_writes, &mut request)?; - req.set_body(bytes::Bytes::from(serialized).into()); - Ok(()) + request.set_body(bytes::Bytes::from(serialized).into()); + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Documents), + &mut request, + ) + .await?; + + Ok(CreateDocumentResponse::try_from(response).await?) + }) } } +type CreateDocument = futures::future::BoxFuture<'static, crate::Result>; + #[derive(Debug, Clone)] pub struct CreateDocumentResponse { pub document_attributes: DocumentAttributes, diff --git a/sdk/data_cosmos/tests/cosmos_document.rs b/sdk/data_cosmos/tests/cosmos_document.rs index 01d8a7b110..da3ac5ee05 100644 --- a/sdk/data_cosmos/tests/cosmos_document.rs +++ b/sdk/data_cosmos/tests/cosmos_document.rs @@ -1,7 +1,7 @@ #![cfg(all(test, feature = "test_e2e"))] use azure_core::Context; use azure_data_cosmos::prelude::{ - CreateDocumentOptions, DeleteDatabaseOptions, GetDocumentOptions, + CreateDocumentBuilder, DeleteDatabaseOptions, GetDocumentOptions, }; use serde::{Deserialize, Serialize}; From 95d4d8fe7f2a89adddaae69aa557c945d9c42da2 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 16:16:18 +0100 Subject: [PATCH 04/13] Create permission --- sdk/data_cosmos/examples/permission_00.rs | 19 ++--- .../examples/user_permission_token.rs | 16 ++-- .../src/clients/permission_client.rs | 33 ++------ .../src/operations/create_permission.rs | 79 ++++++++++++------- .../src/operations/replace_permission.rs | 2 +- .../src/requests/list_permissions_builder.rs | 4 +- sdk/data_cosmos/src/resources/mod.rs | 4 +- .../src/resources/permission/permission.rs | 32 ++++---- .../permission/permission_response.rs | 8 +- .../responses/list_permissions_response.rs | 12 +-- 10 files changed, 101 insertions(+), 108 deletions(-) diff --git a/sdk/data_cosmos/examples/permission_00.rs b/sdk/data_cosmos/examples/permission_00.rs index 2017910e1b..52ecee8e99 100644 --- a/sdk/data_cosmos/examples/permission_00.rs +++ b/sdk/data_cosmos/examples/permission_00.rs @@ -68,13 +68,10 @@ async fn main() -> Result<(), Box> { let permission_mode = get_collection_response.collection.read_permission(); let create_permission_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new() - .consistency_level(&create_user_response) - .expiry_seconds(18000u64), - &permission_mode, - ) + .create_permission(permission_mode) + .consistency_level(&create_user_response) + .expiry_seconds(18000u64) + .into_future() .await .unwrap(); println!( @@ -87,11 +84,9 @@ async fn main() -> Result<(), Box> { let permission_mode = get_collection2_response.collection.all_permission(); let create_permission2_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new().consistency_level(&create_user_response), - &permission_mode, - ) + .create_permission(permission_mode) + .consistency_level(&create_user_response) + .into_future() .await .unwrap(); diff --git a/sdk/data_cosmos/examples/user_permission_token.rs b/sdk/data_cosmos/examples/user_permission_token.rs index 413dd03d31..142e8160d3 100644 --- a/sdk/data_cosmos/examples/user_permission_token.rs +++ b/sdk/data_cosmos/examples/user_permission_token.rs @@ -61,11 +61,9 @@ async fn main() -> Result<(), Box> { let permission_mode = get_collection_response.collection.read_permission(); let create_permission_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &permission_mode, - ) + .create_permission(permission_mode) + .expiry_seconds(18000u64) // 5 hours, max! + .into_future() .await .unwrap(); println!( @@ -137,11 +135,9 @@ async fn main() -> Result<(), Box> { // All includes read and write. let permission_mode = get_collection_response.collection.all_permission(); let create_permission_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &permission_mode, - ) + .create_permission(permission_mode) + .expiry_seconds(18000u64) + .into_future() .await .unwrap(); println!( diff --git a/sdk/data_cosmos/src/clients/permission_client.rs b/sdk/data_cosmos/src/clients/permission_client.rs index 2a38e2f73c..7545496d8e 100644 --- a/sdk/data_cosmos/src/clients/permission_client.rs +++ b/sdk/data_cosmos/src/clients/permission_client.rs @@ -44,29 +44,8 @@ impl PermissionClient { } /// Create the permission - pub async fn create_permission( - &self, - ctx: Context, - options: CreatePermissionOptions, - permission_mode: &PermissionMode<'_>, - ) -> crate::Result> { - let mut request = self.cosmos_client().prepare_request_pipeline( - &format!( - "dbs/{}/users/{}/permissions", - self.database_client().database_name(), - self.user_client().user_name() - ), - http::Method::POST, - ); - - options.decorate_request(&mut request, self.permission_name(), permission_mode)?; - - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Permissions), &mut request) - .await?; - - Ok(PermissionResponse::try_from(response).await?) + pub fn create_permission(&self, permission_mode: PermissionMode) -> CreatePermissionBuilder { + CreatePermissionBuilder::new(self.clone(), permission_mode) } /// Replace the permission @@ -74,8 +53,8 @@ impl PermissionClient { &self, ctx: Context, options: ReplacePermissionOptions, - permission_mode: &PermissionMode<'_>, - ) -> crate::Result> { + permission_mode: &PermissionMode, + ) -> crate::Result { let mut request = self.prepare_request_with_permission_name(http::Method::PUT); options.decorate_request(&mut request, self.permission_name(), permission_mode)?; @@ -93,7 +72,7 @@ impl PermissionClient { &self, ctx: Context, options: GetPermissionOptions, - ) -> crate::Result> { + ) -> crate::Result { let mut request = self.prepare_request_with_permission_name(http::Method::GET); options.decorate_request(&mut request)?; @@ -136,7 +115,7 @@ impl PermissionClient { ) } - fn pipeline(&self) -> &Pipeline { + pub(crate) fn pipeline(&self) -> &Pipeline { self.cosmos_client().pipeline() } } diff --git a/sdk/data_cosmos/src/operations/create_permission.rs b/sdk/data_cosmos/src/operations/create_permission.rs index 7d19740587..586f95d378 100644 --- a/sdk/data_cosmos/src/operations/create_permission.rs +++ b/sdk/data_cosmos/src/operations/create_permission.rs @@ -1,19 +1,25 @@ use crate::prelude::*; -use crate::resources::permission::{ExpirySeconds, PermissionMode}; +use crate::resources::permission::{ExpirySeconds, PermissionMode, PermissionResponse}; -use azure_core::Request as HttpRequest; +use azure_core::Context; #[derive(Debug, Clone)] -pub struct CreatePermissionOptions { +pub struct CreatePermissionBuilder { + client: PermissionClient, expiry_seconds: Option, consistency_level: Option, + permission_mode: PermissionMode, + context: Context, } -impl CreatePermissionOptions { - pub fn new() -> Self { +impl CreatePermissionBuilder { + pub(crate) fn new(client: PermissionClient, permission_mode: PermissionMode) -> Self { Self { + client, expiry_seconds: Some(ExpirySeconds::new(3600)), consistency_level: None, + permission_mode, + context: Context::new(), } } @@ -22,30 +28,47 @@ impl CreatePermissionOptions { consistency_level: ConsistencyLevel => Some(consistency_level), } - pub(crate) fn decorate_request( - &self, - request: &mut HttpRequest, - id: &str, - permission_mode: &PermissionMode<'_>, - ) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; - azure_core::headers::add_optional_header2(&self.expiry_seconds, request)?; - - #[derive(Serialize, Deserialize)] - struct RequestBody<'x> { - id: &'x str, - #[serde(rename = "permissionMode")] - permission_mode: &'x str, - resource: &'x str, - } + pub fn into_future(self) -> CreatePermission { + Box::pin(async move { + let mut request = self.client.cosmos_client().prepare_request_pipeline( + &format!( + "dbs/{}/users/{}/permissions", + self.client.database_client().database_name(), + self.client.user_client().user_name() + ), + http::Method::POST, + ); + + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + azure_core::headers::add_optional_header2(&self.expiry_seconds, &mut request)?; + + #[derive(Serialize, Deserialize)] + struct RequestBody<'x> { + id: &'x str, + #[serde(rename = "permissionMode")] + permission_mode: &'x str, + resource: &'x str, + } - let request_body = RequestBody { - id, - permission_mode: permission_mode.kind(), - resource: permission_mode.resource(), - }; + let request_body = RequestBody { + id: &self.client.permission_name(), + permission_mode: self.permission_mode.kind(), + resource: self.permission_mode.resource(), + }; - request.set_body(bytes::Bytes::from(serde_json::to_string(&request_body)?).into()); - Ok(()) + request.set_body(bytes::Bytes::from(serde_json::to_string(&request_body)?).into()); + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Permissions), + &mut request, + ) + .await?; + + Ok(PermissionResponse::try_from(response).await?) + }) } } + +type CreatePermission = futures::future::BoxFuture<'static, crate::Result>; diff --git a/sdk/data_cosmos/src/operations/replace_permission.rs b/sdk/data_cosmos/src/operations/replace_permission.rs index af535bbdfd..d562fb477d 100644 --- a/sdk/data_cosmos/src/operations/replace_permission.rs +++ b/sdk/data_cosmos/src/operations/replace_permission.rs @@ -26,7 +26,7 @@ impl ReplacePermissionOptions { &self, request: &mut HttpRequest, id: &str, - permission_mode: &PermissionMode<'_>, + permission_mode: &PermissionMode, ) -> crate::Result<()> { azure_core::headers::add_optional_header2(&self.consistency_level, request)?; azure_core::headers::add_optional_header2(&self.expiry_seconds, request)?; diff --git a/sdk/data_cosmos/src/requests/list_permissions_builder.rs b/sdk/data_cosmos/src/requests/list_permissions_builder.rs index f50c43e50c..32e817a315 100644 --- a/sdk/data_cosmos/src/requests/list_permissions_builder.rs +++ b/sdk/data_cosmos/src/requests/list_permissions_builder.rs @@ -36,7 +36,7 @@ impl<'a, 'b> ListPermissionsBuilder<'a, 'b> { max_item_count: i32 => MaxItemCount::new(max_item_count), } - pub async fn execute(&self) -> crate::Result> { + pub async fn execute(&self) -> crate::Result { trace!("ListPermissionsBuilder::execute called"); let request = self.user_client.cosmos_client().prepare_request( @@ -66,7 +66,7 @@ impl<'a, 'b> ListPermissionsBuilder<'a, 'b> { .try_into()?) } - pub fn stream(&self) -> impl Stream>> + '_ { + pub fn stream(&self) -> impl Stream> + '_ { #[derive(Debug, Clone, PartialEq)] enum States { Init, diff --git a/sdk/data_cosmos/src/resources/mod.rs b/sdk/data_cosmos/src/resources/mod.rs index 8d9d6abbfe..15c48bf9d6 100644 --- a/sdk/data_cosmos/src/resources/mod.rs +++ b/sdk/data_cosmos/src/resources/mod.rs @@ -40,12 +40,12 @@ pub trait Resource { fn uri(&self) -> &str; /// Get the read permissions for the resource - fn read_permission(&self) -> PermissionMode<'_> { + fn read_permission(&self) -> PermissionMode { PermissionMode::read(self) } /// Get all permissions for the resource - fn all_permission(&self) -> PermissionMode<'_> { + fn all_permission(&self) -> PermissionMode { PermissionMode::all(self) } } diff --git a/sdk/data_cosmos/src/resources/permission/permission.rs b/sdk/data_cosmos/src/resources/permission/permission.rs index 63add16cfa..3f3f4996d1 100644 --- a/sdk/data_cosmos/src/resources/permission/permission.rs +++ b/sdk/data_cosmos/src/resources/permission/permission.rs @@ -11,16 +11,16 @@ use std::borrow::Cow; /// attachments, stored procedures, triggers, and user-defined functions for a particular user. /// You can learn more about permissions [here](https://docs.microsoft.com/rest/api/cosmos-db/permissions). #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Permission<'a> { +pub struct Permission { /// The unique name that identifies the permission. - pub id: Cow<'a, str>, + pub id: String, #[serde(flatten)] /// The access mode on the resource for the user /// /// Represented as both "permissionMode" and "resource" in the JSON representation. - pub permission_mode: PermissionMode<'a>, + pub permission_mode: PermissionMode, #[serde(rename = "_rid")] - rid: Cow<'a, str>, + rid: String, /// The last updated timestamp of the resource. /// /// Represented as "_ts" in the JSON representation. @@ -30,12 +30,12 @@ pub struct Permission<'a> { /// /// Represented as "_self" in the JSON representation. #[serde(rename = "_self")] - pub uri: Cow<'a, str>, + pub uri: String, /// The resource etag required for optimistic concurrency control. /// /// Represented as "_etag" in the JSON representation. #[serde(rename = "_etag")] - pub etag: Cow<'a, str>, + pub etag: String, /// The resource token for the particular resource and user. /// /// Represented as "_token" in the JSON representation. @@ -51,22 +51,22 @@ pub struct Permission<'a> { /// Constructing a `PermissionMode` manually is error prone. Use one of the constructor methods /// (i.e., [`PermissionMode::read`] or [`PermissionMode::all`]) or get a permission directly /// from a resource (e.g., `Collection::read_permission`). -pub enum PermissionMode<'a> { +pub enum PermissionMode { /// read, write, and delete access - All(Cow<'a, str>), + All(Cow<'static, str>), /// read access only - Read(Cow<'a, str>), + Read(Cow<'static, str>), } -impl<'a> PermissionMode<'a> { +impl PermissionMode { /// Read permission for a given resource - pub fn read(resource: &'a T) -> Self { - PermissionMode::Read(Cow::Borrowed(resource.uri())) + pub fn read(resource: &T) -> Self { + PermissionMode::Read(Cow::Owned(resource.uri().to_owned())) } /// Read, write, and delete permissions for a given resource - pub fn all(resource: &'a T) -> Self { - PermissionMode::All(Cow::Borrowed(resource.uri())) + pub fn all(resource: &T) -> Self { + PermissionMode::All(Cow::Owned(resource.uri().to_owned())) } /// The kind of permission mode as a string. Either "All" or "Read". @@ -86,7 +86,7 @@ impl<'a> PermissionMode<'a> { } } -impl<'a> std::convert::TryFrom<&[u8]> for Permission<'a> { +impl std::convert::TryFrom<&[u8]> for Permission { type Error = crate::Error; fn try_from(slice: &[u8]) -> Result { @@ -112,7 +112,7 @@ mod tests { #[test] fn parse_permission() { - let permission: Permission<'_> = serde_json::from_str(PERMISSION_JSON).unwrap(); + let permission: Permission = serde_json::from_str(PERMISSION_JSON).unwrap(); assert_eq!( permission.permission_token, diff --git a/sdk/data_cosmos/src/resources/permission/permission_response.rs b/sdk/data_cosmos/src/resources/permission/permission_response.rs index e53a287347..381d6a3002 100644 --- a/sdk/data_cosmos/src/resources/permission/permission_response.rs +++ b/sdk/data_cosmos/src/resources/permission/permission_response.rs @@ -6,8 +6,8 @@ use azure_core::{collect_pinned_stream, Response as HttpResponse}; use super::Permission; #[derive(Debug, Clone, PartialEq)] -pub struct PermissionResponse<'a> { - pub permission: Permission<'a>, +pub struct PermissionResponse { + pub permission: Permission, pub charge: f64, pub activity_id: uuid::Uuid, pub etag: String, @@ -16,8 +16,8 @@ pub struct PermissionResponse<'a> { pub alt_content_path: String, } -impl<'a> PermissionResponse<'a> { - pub async fn try_from(response: HttpResponse) -> crate::Result> { +impl PermissionResponse { + pub async fn try_from(response: HttpResponse) -> crate::Result { let (_status_code, headers, pinned_stream) = response.deconstruct(); let body = collect_pinned_stream(pinned_stream).await?; diff --git a/sdk/data_cosmos/src/responses/list_permissions_response.rs b/sdk/data_cosmos/src/responses/list_permissions_response.rs index 8b2525c5c5..268b40e4f1 100644 --- a/sdk/data_cosmos/src/responses/list_permissions_response.rs +++ b/sdk/data_cosmos/src/responses/list_permissions_response.rs @@ -4,8 +4,8 @@ use azure_core::headers::{continuation_token_from_headers_optional, session_toke use http::response::Response; #[derive(Debug, Clone, PartialEq)] -pub struct ListPermissionsResponse<'a> { - pub permissions: Vec>, +pub struct ListPermissionsResponse { + pub permissions: Vec, pub charge: f64, pub activity_id: uuid::Uuid, pub session_token: String, @@ -14,7 +14,7 @@ pub struct ListPermissionsResponse<'a> { pub continuation_token: Option, } -impl<'a> std::convert::TryFrom> for ListPermissionsResponse<'a> { +impl std::convert::TryFrom> for ListPermissionsResponse { type Error = crate::Error; fn try_from(response: Response) -> Result { @@ -22,15 +22,15 @@ impl<'a> std::convert::TryFrom> for ListPermissionsRespon let body = response.body(); #[derive(Debug, Deserialize)] - struct Response<'b> { + struct Response { _rid: String, #[serde(rename = "Permissions")] - permissions: Vec>, + permissions: Vec, _count: u32, } // first get the Cosmos REST API permission - let response: Response<'_> = serde_json::from_slice(body)?; + let response: Response = serde_json::from_slice(body)?; debug!("response == {:#?}", response); // now convert every Cosmos REST API permission From 94eebdd0d53c2025a5e3dd765b365370af9275e8 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 16:29:48 +0100 Subject: [PATCH 05/13] CreateUser::into_future --- sdk/data_cosmos/examples/permission_00.rs | 4 +- sdk/data_cosmos/examples/user_00.rs | 3 +- .../examples/user_permission_token.rs | 4 +- sdk/data_cosmos/src/clients/user_client.rs | 21 +------ .../src/operations/create_document.rs | 9 +++ .../src/operations/create_permission.rs | 9 +++ sdk/data_cosmos/src/operations/create_user.rs | 62 ++++++++++++++----- 7 files changed, 72 insertions(+), 40 deletions(-) diff --git a/sdk/data_cosmos/examples/permission_00.rs b/sdk/data_cosmos/examples/permission_00.rs index 52ecee8e99..454d19fdbb 100644 --- a/sdk/data_cosmos/examples/permission_00.rs +++ b/sdk/data_cosmos/examples/permission_00.rs @@ -58,9 +58,7 @@ async fn main() -> Result<(), Box> { get_collection2_response ); - let create_user_response = user_client - .create_user(Context::new(), CreateUserOptions::default()) - .await?; + let create_user_response = user_client.create_user().into_future().await?; println!("create_user_response == {:#?}", create_user_response); // create the first permission! diff --git a/sdk/data_cosmos/examples/user_00.rs b/sdk/data_cosmos/examples/user_00.rs index 586a115d9e..0beda165d2 100644 --- a/sdk/data_cosmos/examples/user_00.rs +++ b/sdk/data_cosmos/examples/user_00.rs @@ -30,7 +30,8 @@ async fn main() -> Result<(), Box> { let user_client = database_client.clone().into_user_client(user_name.clone()); let create_user_response = user_client - .create_user(Context::new(), CreateUserOptions::new()) + .create_user() + .into_future() .await?; println!("create_user_response == {:#?}", create_user_response); diff --git a/sdk/data_cosmos/examples/user_permission_token.rs b/sdk/data_cosmos/examples/user_permission_token.rs index 142e8160d3..7e051effd0 100644 --- a/sdk/data_cosmos/examples/user_permission_token.rs +++ b/sdk/data_cosmos/examples/user_permission_token.rs @@ -39,9 +39,7 @@ async fn main() -> Result<(), Box> { .await?; println!("get_collection_response == {:#?}", get_collection_response); - let create_user_response = user_client - .create_user(Context::new(), CreateUserOptions::default()) - .await?; + let create_user_response = user_client.create_user().into_future().await?; println!("create_user_response == {:#?}", create_user_response); // test list documents diff --git a/sdk/data_cosmos/src/clients/user_client.rs b/sdk/data_cosmos/src/clients/user_client.rs index 48a1101238..d95b92fb5d 100644 --- a/sdk/data_cosmos/src/clients/user_client.rs +++ b/sdk/data_cosmos/src/clients/user_client.rs @@ -39,23 +39,8 @@ impl UserClient { } /// Create the user - pub async fn create_user( - &self, - ctx: Context, - options: CreateUserOptions, - ) -> crate::Result { - let mut request = self.cosmos_client().prepare_request_pipeline( - &format!("dbs/{}/users", self.database_client.database_name()), - http::Method::POST, - ); - - options.decorate_request(&mut request, self.user_name())?; - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Users), &mut request) - .await?; - - Ok(UserResponse::try_from(response).await?) + pub fn create_user(&self) -> CreateUserBuilder { + CreateUserBuilder::new(self.clone()) } /// Get the user @@ -137,7 +122,7 @@ impl UserClient { self.cosmos_client().http_client() } - fn pipeline(&self) -> &Pipeline { + pub(crate) fn pipeline(&self) -> &Pipeline { self.cosmos_client().pipeline() } } diff --git a/sdk/data_cosmos/src/operations/create_document.rs b/sdk/data_cosmos/src/operations/create_document.rs index 62e3e8cd9b..5b8fb737ec 100644 --- a/sdk/data_cosmos/src/operations/create_document.rs +++ b/sdk/data_cosmos/src/operations/create_document.rs @@ -94,6 +94,15 @@ impl CreateDocumentBuilder { type CreateDocument = futures::future::BoxFuture<'static, crate::Result>; +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for CreateDocumentBuilder { + type Future = CreateDocument; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) + } +} + #[derive(Debug, Clone)] pub struct CreateDocumentResponse { pub document_attributes: DocumentAttributes, diff --git a/sdk/data_cosmos/src/operations/create_permission.rs b/sdk/data_cosmos/src/operations/create_permission.rs index 586f95d378..5d23a3afe7 100644 --- a/sdk/data_cosmos/src/operations/create_permission.rs +++ b/sdk/data_cosmos/src/operations/create_permission.rs @@ -72,3 +72,12 @@ impl CreatePermissionBuilder { } type CreatePermission = futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for CreatePermissionBuilder { + type Future = CreatePermission; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) + } +} \ No newline at end of file diff --git a/sdk/data_cosmos/src/operations/create_user.rs b/sdk/data_cosmos/src/operations/create_user.rs index 9f1b0ee9d9..e0ce193c12 100644 --- a/sdk/data_cosmos/src/operations/create_user.rs +++ b/sdk/data_cosmos/src/operations/create_user.rs @@ -1,15 +1,19 @@ -use crate::prelude::*; -use azure_core::Request as HttpRequest; +use crate::{prelude::*, resources::user::UserResponse}; +use azure_core::Context; -#[derive(Debug, Clone, Default)] -pub struct CreateUserOptions { +#[derive(Debug, Clone)] +pub struct CreateUserBuilder { + client: UserClient, consistency_level: Option, + context: Context, } -impl CreateUserOptions { - pub fn new() -> Self { +impl CreateUserBuilder { + pub(crate) fn new(client: UserClient) -> Self { Self { + client, consistency_level: None, + context: Context::new(), } } @@ -17,15 +21,43 @@ impl CreateUserOptions { consistency_level: ConsistencyLevel => Some(consistency_level), } - pub(crate) fn decorate_request( - &self, - request: &mut HttpRequest, - user_name: &str, - ) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; - let body = CreateUserBody { id: user_name }; - request.set_body(bytes::Bytes::from(serde_json::to_string(&body)?).into()); - Ok(()) + pub fn into_future(self) -> CreateUser { + Box::pin(async move { + let mut request = self.client.cosmos_client().prepare_request_pipeline( + &format!( + "dbs/{}/users", + self.client.database_client().database_name() + ), + http::Method::POST, + ); + + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + let body = CreateUserBody { + id: self.client.user_name(), + }; + request.set_body(bytes::Bytes::from(serde_json::to_string(&body)?).into()); + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Users), + &mut request, + ) + .await?; + + Ok(UserResponse::try_from(response).await?) + }) + } +} + +type CreateUser = futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for CreateUserBuilder { + type Future = CreateUser; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) } } From 94cf13d2838e69a7c41b96c222425f2147d36f59 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 16:40:00 +0100 Subject: [PATCH 06/13] DeleteCollection::into_future --- .../examples/create_delete_database.rs | 4 +- sdk/data_cosmos/examples/document_00.rs | 3 +- .../src/clients/collection_client.rs | 22 +++------ .../src/operations/delete_collection.rs | 45 ++++++++++++++++--- 4 files changed, 47 insertions(+), 27 deletions(-) diff --git a/sdk/data_cosmos/examples/create_delete_database.rs b/sdk/data_cosmos/examples/create_delete_database.rs index 147531f8d0..4e1017c332 100644 --- a/sdk/data_cosmos/examples/create_delete_database.rs +++ b/sdk/data_cosmos/examples/create_delete_database.rs @@ -70,9 +70,7 @@ async fn main() -> Result<(), Box> { println!("res == {:#?}", res); } - let delete_response = db_collection - .delete_collection(Context::new(), DeleteCollectionOptions::new()) - .await?; + let delete_response = db_collection.delete_collection().into_future().await?; println!("collection deleted: {:#?}", delete_response); } diff --git a/sdk/data_cosmos/examples/document_00.rs b/sdk/data_cosmos/examples/document_00.rs index b446eb8d93..cdc7fd590a 100644 --- a/sdk/data_cosmos/examples/document_00.rs +++ b/sdk/data_cosmos/examples/document_00.rs @@ -188,7 +188,8 @@ async fn main() -> Result<(), Box> { .clone() .into_database_client(DATABASE.to_owned()) .into_collection_client(COLLECTION.to_owned()) - .delete_collection(Context::new(), DeleteCollectionOptions::new()) + .delete_collection() + .into_future() .await?; println!("collection deleted"); diff --git a/sdk/data_cosmos/src/clients/collection_client.rs b/sdk/data_cosmos/src/clients/collection_client.rs index ca33ad49ae..0a6b34fe6f 100644 --- a/sdk/data_cosmos/src/clients/collection_client.rs +++ b/sdk/data_cosmos/src/clients/collection_client.rs @@ -60,21 +60,8 @@ impl CollectionClient { } /// Delete a collection - pub async fn delete_collection( - &self, - ctx: Context, - options: DeleteCollectionOptions, - ) -> crate::Result { - let mut request = self.prepare_request_with_collection_name(http::Method::DELETE); - - options.decorate_request(&mut request)?; - - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Collections), &mut request) - .await?; - - Ok(DeleteCollectionResponse::try_from(response).await?) + pub fn delete_collection(&self) -> DeleteCollectionBuilder { + DeleteCollectionBuilder::new(self.clone()) } /// Replace a collection @@ -163,7 +150,10 @@ impl CollectionClient { StoredProcedureClient::new(self, stored_procedure_name) } - fn prepare_request_with_collection_name(&self, http_method: http::Method) -> Request { + pub(crate) fn prepare_request_with_collection_name( + &self, + http_method: http::Method, + ) -> Request { let path = &format!( "dbs/{}/colls/{}", self.database_client().database_name(), diff --git a/sdk/data_cosmos/src/operations/delete_collection.rs b/sdk/data_cosmos/src/operations/delete_collection.rs index 1914cc75ec..b50f48c1c4 100644 --- a/sdk/data_cosmos/src/operations/delete_collection.rs +++ b/sdk/data_cosmos/src/operations/delete_collection.rs @@ -1,18 +1,22 @@ use crate::prelude::*; use crate::{headers::from_headers::*, ResourceQuota}; use azure_core::headers::{content_type_from_headers, session_token_from_headers}; -use azure_core::{Request as HttpRequest, Response as HttpResponse}; +use azure_core::{Context, Response as HttpResponse}; use chrono::{DateTime, Utc}; #[derive(Debug, Clone)] -pub struct DeleteCollectionOptions { +pub struct DeleteCollectionBuilder { + client: CollectionClient, consistency_level: Option, + context: Context, } -impl DeleteCollectionOptions { - pub fn new() -> Self { +impl DeleteCollectionBuilder { + pub fn new(client: CollectionClient) -> Self { Self { + client, consistency_level: None, + context: Context::new(), } } @@ -20,10 +24,37 @@ impl DeleteCollectionOptions { consistency_level: ConsistencyLevel => Some(consistency_level), } - pub(crate) fn decorate_request(&self, request: &mut HttpRequest) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; + pub fn into_future(self) -> DeleteCollection { + Box::pin(async move { + let mut request = self + .client + .prepare_request_with_collection_name(http::Method::DELETE); - Ok(()) + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Collections), + &mut request, + ) + .await?; + + Ok(DeleteCollectionResponse::try_from(response).await?) + }) + } +} + +type DeleteCollection = + futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for DeleteCollectionBuilder { + type Future = DeleteCollection; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) } } From e56a4414043c7b88b30172176656483a87cfb17f Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 16:56:21 +0100 Subject: [PATCH 07/13] DeleteDatabase::into_future --- .../examples/create_delete_database.rs | 3 +- sdk/data_cosmos/examples/document_00.rs | 3 +- .../src/clients/database_client.rs | 19 +------- .../src/operations/create_collection.rs | 1 + .../src/operations/create_document.rs | 5 +- .../src/operations/create_permission.rs | 1 + sdk/data_cosmos/src/operations/create_user.rs | 1 + .../src/operations/delete_collection.rs | 1 + .../src/operations/delete_database.rs | 46 ++++++++++++++++--- sdk/data_cosmos/tests/cosmos_document.rs | 2 +- 10 files changed, 54 insertions(+), 28 deletions(-) diff --git a/sdk/data_cosmos/examples/create_delete_database.rs b/sdk/data_cosmos/examples/create_delete_database.rs index 4e1017c332..dbeab5f539 100644 --- a/sdk/data_cosmos/examples/create_delete_database.rs +++ b/sdk/data_cosmos/examples/create_delete_database.rs @@ -76,7 +76,8 @@ async fn main() -> Result<(), Box> { let resp = client .into_database_client(database_name) - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await?; println!("database deleted. resp == {:#?}", resp); diff --git a/sdk/data_cosmos/examples/document_00.rs b/sdk/data_cosmos/examples/document_00.rs index cdc7fd590a..842e15b740 100644 --- a/sdk/data_cosmos/examples/document_00.rs +++ b/sdk/data_cosmos/examples/document_00.rs @@ -196,7 +196,8 @@ async fn main() -> Result<(), Box> { // And then we delete the database. client .into_database_client(database.id) - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await?; println!("database deleted"); diff --git a/sdk/data_cosmos/src/clients/database_client.rs b/sdk/data_cosmos/src/clients/database_client.rs index 3581421dfe..fd815d564e 100644 --- a/sdk/data_cosmos/src/clients/database_client.rs +++ b/sdk/data_cosmos/src/clients/database_client.rs @@ -77,23 +77,8 @@ impl DatabaseClient { } /// Delete the database - pub async fn delete_database( - &self, - ctx: Context, - options: DeleteDatabaseOptions, - ) -> crate::Result { - let mut request = self.cosmos_client().prepare_request_pipeline( - &format!("dbs/{}", self.database_name()), - http::Method::DELETE, - ); - - options.decorate_request(&mut request)?; - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Databases), &mut request) - .await?; - - Ok(DeleteDatabaseResponse::try_from(response).await?) + pub fn delete_database(&self) -> DeleteDatabaseBuilder { + DeleteDatabaseBuilder::new(self.clone()) } /// List collections in the database diff --git a/sdk/data_cosmos/src/operations/create_collection.rs b/sdk/data_cosmos/src/operations/create_collection.rs index 170ffbf62c..5daa95087e 100644 --- a/sdk/data_cosmos/src/operations/create_collection.rs +++ b/sdk/data_cosmos/src/operations/create_collection.rs @@ -37,6 +37,7 @@ impl CreateCollectionBuilder { consistency_level: ConsistencyLevel => Some(consistency_level), indexing_policy: IndexingPolicy => Some(indexing_policy), offer: Offer => Some(offer), + context: Context => context, } pub fn into_future(self) -> CreateCollection { diff --git a/sdk/data_cosmos/src/operations/create_document.rs b/sdk/data_cosmos/src/operations/create_document.rs index 5b8fb737ec..8d6a755748 100644 --- a/sdk/data_cosmos/src/operations/create_document.rs +++ b/sdk/data_cosmos/src/operations/create_document.rs @@ -49,6 +49,7 @@ impl CreateDocumentBuilder { allow_tentative_writes: TentativeWritesAllowance, is_upsert: bool => if is_upsert { IsUpsert::Yes } else { IsUpsert::No }, indexing_directive: IndexingDirective, + context: Context => context, } pub fn partition_key( @@ -95,7 +96,9 @@ impl CreateDocumentBuilder { type CreateDocument = futures::future::BoxFuture<'static, crate::Result>; #[cfg(feature = "into_future")] -impl std::future::IntoFuture for CreateDocumentBuilder { +impl std::future::IntoFuture + for CreateDocumentBuilder +{ type Future = CreateDocument; type Output = ::Output; fn into_future(self) -> Self::Future { diff --git a/sdk/data_cosmos/src/operations/create_permission.rs b/sdk/data_cosmos/src/operations/create_permission.rs index 5d23a3afe7..3be9a52bcd 100644 --- a/sdk/data_cosmos/src/operations/create_permission.rs +++ b/sdk/data_cosmos/src/operations/create_permission.rs @@ -26,6 +26,7 @@ impl CreatePermissionBuilder { setters! { expiry_seconds: u64 => Some(ExpirySeconds::new(expiry_seconds)), consistency_level: ConsistencyLevel => Some(consistency_level), + context: Context => context, } pub fn into_future(self) -> CreatePermission { diff --git a/sdk/data_cosmos/src/operations/create_user.rs b/sdk/data_cosmos/src/operations/create_user.rs index e0ce193c12..d67389771e 100644 --- a/sdk/data_cosmos/src/operations/create_user.rs +++ b/sdk/data_cosmos/src/operations/create_user.rs @@ -19,6 +19,7 @@ impl CreateUserBuilder { setters! { consistency_level: ConsistencyLevel => Some(consistency_level), + context: Context => context, } pub fn into_future(self) -> CreateUser { diff --git a/sdk/data_cosmos/src/operations/delete_collection.rs b/sdk/data_cosmos/src/operations/delete_collection.rs index b50f48c1c4..f58b8df1fc 100644 --- a/sdk/data_cosmos/src/operations/delete_collection.rs +++ b/sdk/data_cosmos/src/operations/delete_collection.rs @@ -22,6 +22,7 @@ impl DeleteCollectionBuilder { setters! { consistency_level: ConsistencyLevel => Some(consistency_level), + context: Context => context, } pub fn into_future(self) -> DeleteCollection { diff --git a/sdk/data_cosmos/src/operations/delete_database.rs b/sdk/data_cosmos/src/operations/delete_database.rs index 232a2418f7..f48e537722 100644 --- a/sdk/data_cosmos/src/operations/delete_database.rs +++ b/sdk/data_cosmos/src/operations/delete_database.rs @@ -2,28 +2,60 @@ use crate::headers::from_headers::*; use crate::prelude::*; use crate::ResourceQuota; use azure_core::headers::session_token_from_headers; -use azure_core::Request as HttpRequest; +use azure_core::Context; use azure_core::Response as HttpResponse; #[derive(Debug, Clone)] -pub struct DeleteDatabaseOptions { +pub struct DeleteDatabaseBuilder { + client: DatabaseClient, consistency_level: Option, + context: Context, } -impl DeleteDatabaseOptions { - pub fn new() -> Self { +impl DeleteDatabaseBuilder { + pub(crate) fn new(client: DatabaseClient) -> Self { Self { + client, consistency_level: None, + context: Context::new(), } } setters! { consistency_level: ConsistencyLevel => Some(consistency_level), + context: Context => context, } - pub fn decorate_request(&self, request: &mut HttpRequest) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; - Ok(()) + pub fn into_future(self) -> DeleteDatabase { + Box::pin(async move { + let mut request = self.client.cosmos_client().prepare_request_pipeline( + &format!("dbs/{}", self.client.database_name()), + http::Method::DELETE, + ); + + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Databases), + &mut request, + ) + .await?; + + Ok(DeleteDatabaseResponse::try_from(response).await?) + }) + } +} + +type DeleteDatabase = futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for DeleteDatabaseBuilder { + type Future = DeleteDatabase; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) } } diff --git a/sdk/data_cosmos/tests/cosmos_document.rs b/sdk/data_cosmos/tests/cosmos_document.rs index da3ac5ee05..cef3085f81 100644 --- a/sdk/data_cosmos/tests/cosmos_document.rs +++ b/sdk/data_cosmos/tests/cosmos_document.rs @@ -1,7 +1,7 @@ #![cfg(all(test, feature = "test_e2e"))] use azure_core::Context; use azure_data_cosmos::prelude::{ - CreateDocumentBuilder, DeleteDatabaseOptions, GetDocumentOptions, + CreateDocumentBuilder, DeleteDatabaseBuilder, GetDocumentOptions, }; use serde::{Deserialize, Serialize}; From fdacd8ef2f14630564398a8ed6b65cbcbf833568 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 17:15:05 +0100 Subject: [PATCH 08/13] DeleteDocument::into_future --- .../examples/document_entries_00.rs | 6 +- sdk/data_cosmos/examples/readme.rs | 11 ++- .../examples/remove_all_documents.rs | 4 +- .../src/clients/document_client.rs | 23 ++----- .../src/operations/delete_document.rs | 67 +++++++++++++------ 5 files changed, 61 insertions(+), 50 deletions(-) diff --git a/sdk/data_cosmos/examples/document_entries_00.rs b/sdk/data_cosmos/examples/document_entries_00.rs index e18f404780..8c393ed6b8 100644 --- a/sdk/data_cosmos/examples/document_entries_00.rs +++ b/sdk/data_cosmos/examples/document_entries_00.rs @@ -173,10 +173,8 @@ async fn main() -> Result<(), Box> { client .clone() .into_document_client(id.clone(), &id)? - .delete_document( - Context::new(), - DeleteDocumentOptions::new().consistency_level(&response), - ) + .delete_document() + .into_future() .await?; } println!("Cleaned up"); diff --git a/sdk/data_cosmos/examples/readme.rs b/sdk/data_cosmos/examples/readme.rs index b90464e18c..6dc7a977c6 100644 --- a/sdk/data_cosmos/examples/readme.rs +++ b/sdk/data_cosmos/examples/readme.rs @@ -1,4 +1,3 @@ -use azure_core::Context; use serde::{Deserialize, Serialize}; // Using the prelude module of the Cosmos crate makes easier to use the Rust Azure SDK for Cosmos. use azure_data_cosmos::prelude::*; @@ -147,12 +146,10 @@ async fn main() -> Result<(), Box> { collection_client .clone() .into_document_client(document.result.id.clone(), &document.result.a_number)? - .delete_document( - Context::new(), - DeleteDocumentOptions::new() - .consistency_level(session_token.clone()) - .if_match_condition(&document.document_attributes), - ) + .delete_document() + .consistency_level(session_token.clone()) + .if_match_condition(&document.document_attributes) + .into_future() .await?; } diff --git a/sdk/data_cosmos/examples/remove_all_documents.rs b/sdk/data_cosmos/examples/remove_all_documents.rs index bdcce4b876..31b357d1f1 100644 --- a/sdk/data_cosmos/examples/remove_all_documents.rs +++ b/sdk/data_cosmos/examples/remove_all_documents.rs @@ -1,4 +1,3 @@ -use azure_core::prelude::*; use azure_data_cosmos::prelude::*; use futures::stream::StreamExt; use serde_json::Value; @@ -74,7 +73,8 @@ async fn main() -> Result<(), Box> { client .clone() .into_document_client(id.clone(), &partition_key)? - .delete_document(Context::new(), DeleteDocumentOptions::new()) + .delete_document() + .into_future() .await?; } diff --git a/sdk/data_cosmos/src/clients/document_client.rs b/sdk/data_cosmos/src/clients/document_client.rs index 42b18d65fb..7a9ff24b64 100644 --- a/sdk/data_cosmos/src/clients/document_client.rs +++ b/sdk/data_cosmos/src/clients/document_client.rs @@ -101,22 +101,8 @@ impl DocumentClient { } /// Delete a document - pub async fn delete_document( - &self, - ctx: Context, - options: DeleteDocumentOptions, - ) -> crate::Result { - let mut request = self.prepare_request_pipeline_with_document_name(http::Method::DELETE); - - options.decorate_request(&mut request, self.partition_key_serialized())?; - - let response = self - .cosmos_client() - .pipeline() - .send(ctx.clone().insert(ResourceType::Documents), &mut request) - .await?; - - DeleteDocumentResponse::try_from(response).await + pub fn delete_document(&self) -> DeleteDocumentBuilder { + DeleteDocumentBuilder::new(self.clone()) } /// List all attachments for a document @@ -132,7 +118,10 @@ impl DocumentClient { AttachmentClient::new(self, attachment_name) } - fn prepare_request_pipeline_with_document_name(&self, method: http::Method) -> Request { + pub(crate) fn prepare_request_pipeline_with_document_name( + &self, + method: http::Method, + ) -> Request { self.cosmos_client().prepare_request_pipeline( &format!( "dbs/{}/colls/{}/docs/{}", diff --git a/sdk/data_cosmos/src/operations/delete_document.rs b/sdk/data_cosmos/src/operations/delete_document.rs index 76017bc07d..f9da6ddcf7 100644 --- a/sdk/data_cosmos/src/operations/delete_document.rs +++ b/sdk/data_cosmos/src/operations/delete_document.rs @@ -1,24 +1,30 @@ +use crate::headers::from_headers::*; use crate::prelude::*; +use azure_core::headers::session_token_from_headers; use azure_core::prelude::*; -use azure_core::{Request as HttpRequest, Response as HttpResponse}; +use azure_core::Response as HttpResponse; use chrono::{DateTime, Utc}; #[derive(Debug, Clone)] -pub struct DeleteDocumentOptions { +pub struct DeleteDocumentBuilder { + client: DocumentClient, if_match_condition: Option, if_modified_since: Option, consistency_level: Option, allow_tentative_writes: TentativeWritesAllowance, + context: Context, } -impl DeleteDocumentOptions { - pub fn new() -> DeleteDocumentOptions { +impl DeleteDocumentBuilder { + pub(crate) fn new(client: DocumentClient) -> DeleteDocumentBuilder { Self { + client, if_match_condition: None, if_modified_since: None, consistency_level: None, allow_tentative_writes: TentativeWritesAllowance::Deny, + context: Context::new(), } } @@ -27,29 +33,50 @@ impl DeleteDocumentOptions { if_match_condition: IfMatchCondition => Some(if_match_condition), allow_tentative_writes: TentativeWritesAllowance, if_modified_since: DateTime => Some(IfModifiedSince::new(if_modified_since)), + context: Context => context, } - pub fn decorate_request( - &self, - request: &mut HttpRequest, - serialized_partition_key: &str, - ) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.if_match_condition, request)?; - azure_core::headers::add_optional_header2(&self.if_modified_since, request)?; - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; - azure_core::headers::add_mandatory_header2(&self.allow_tentative_writes, request)?; + pub fn into_future(self) -> DeleteDocument { + Box::pin(async move { + let mut request = self + .client + .prepare_request_pipeline_with_document_name(http::Method::DELETE); + + azure_core::headers::add_optional_header2(&self.if_match_condition, &mut request)?; + azure_core::headers::add_optional_header2(&self.if_modified_since, &mut request)?; + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + azure_core::headers::add_mandatory_header2(&self.allow_tentative_writes, &mut request)?; - crate::cosmos_entity::add_as_partition_key_header_serialized2( - serialized_partition_key, - request, - ); + crate::cosmos_entity::add_as_partition_key_header_serialized2( + &self.client.partition_key_serialized(), + &mut request, + ); - Ok(()) + let response = self + .client + .cosmos_client() + .pipeline() + .send( + self.context.clone().insert(ResourceType::Documents), + &mut request, + ) + .await?; + + DeleteDocumentResponse::try_from(response).await + }) } } -use crate::headers::from_headers::*; -use azure_core::headers::session_token_from_headers; +type DeleteDocument = futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for DeleteDocumentBuilder { + type Future = DeleteDocument; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) + } +} #[derive(Debug, Clone)] pub struct DeleteDocumentResponse { From 7f47df1f8e842495eef1e21bcc1b5ee92bd7ac0d Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 24 Feb 2022 17:23:53 +0100 Subject: [PATCH 09/13] DeletePermission::into_future --- sdk/data_cosmos/examples/permission_00.rs | 11 ++--- .../examples/user_permission_token.rs | 4 +- .../src/clients/permission_client.rs | 17 +------ .../src/operations/delete_permission.rs | 46 ++++++++++++++++--- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/sdk/data_cosmos/examples/permission_00.rs b/sdk/data_cosmos/examples/permission_00.rs index 454d19fdbb..73ff089593 100644 --- a/sdk/data_cosmos/examples/permission_00.rs +++ b/sdk/data_cosmos/examples/permission_00.rs @@ -138,12 +138,11 @@ async fn main() -> Result<(), Box> { ); let delete_permission_response = permission_client - .delete_permission( - Context::new(), - DeletePermissionOptions::new().consistency_level(ConsistencyLevel::Session( - replace_permission_response.session_token, - )), - ) + .delete_permission() + .consistency_level(ConsistencyLevel::Session( + replace_permission_response.session_token, + )) + .into_future() .await .unwrap(); diff --git a/sdk/data_cosmos/examples/user_permission_token.rs b/sdk/data_cosmos/examples/user_permission_token.rs index 7e051effd0..467595b63e 100644 --- a/sdk/data_cosmos/examples/user_permission_token.rs +++ b/sdk/data_cosmos/examples/user_permission_token.rs @@ -126,9 +126,7 @@ async fn main() -> Result<(), Box> { Err(error) => println!("Insert failed: {:#?}", error), } - permission_client - .delete_permission(Context::new(), DeletePermissionOptions::new()) - .await?; + permission_client.delete_permission().into_future().await?; // All includes read and write. let permission_mode = get_collection_response.collection.all_permission(); diff --git a/sdk/data_cosmos/src/clients/permission_client.rs b/sdk/data_cosmos/src/clients/permission_client.rs index 7545496d8e..a8adaf4afc 100644 --- a/sdk/data_cosmos/src/clients/permission_client.rs +++ b/sdk/data_cosmos/src/clients/permission_client.rs @@ -86,21 +86,8 @@ impl PermissionClient { } /// Delete the permission - pub async fn delete_permission( - &self, - ctx: Context, - options: DeletePermissionOptions, - ) -> crate::Result { - let mut request = self.prepare_request_with_permission_name(http::Method::DELETE); - - options.decorate_request(&mut request)?; - - let response = self - .pipeline() - .send(ctx.clone().insert(ResourceType::Permissions), &mut request) - .await?; - - Ok(DeletePermissionResponse::try_from(response).await?) + pub fn delete_permission(&self) -> DeletePermissionBuilder { + DeletePermissionBuilder::new(self.clone()) } pub(crate) fn prepare_request_with_permission_name(&self, method: http::Method) -> Request { diff --git a/sdk/data_cosmos/src/operations/delete_permission.rs b/sdk/data_cosmos/src/operations/delete_permission.rs index fa70c2f19f..a170cfd767 100644 --- a/sdk/data_cosmos/src/operations/delete_permission.rs +++ b/sdk/data_cosmos/src/operations/delete_permission.rs @@ -2,29 +2,61 @@ use crate::headers::from_headers::*; use crate::prelude::*; use azure_core::headers::session_token_from_headers; -use azure_core::Request as HttpRequest; +use azure_core::Context; use azure_core::Response as HttpResponse; #[derive(Debug, Clone)] -pub struct DeletePermissionOptions { +pub struct DeletePermissionBuilder { + client: PermissionClient, consistency_level: Option, + context: Context, } -impl DeletePermissionOptions { - pub fn new() -> Self { +impl DeletePermissionBuilder { + pub(crate) fn new(client: PermissionClient) -> Self { Self { + client, consistency_level: None, + context: Context::new(), } } setters! { consistency_level: ConsistencyLevel => Some(consistency_level), + context: Context => context, } - pub(crate) fn decorate_request(&self, request: &mut HttpRequest) -> crate::Result<()> { - azure_core::headers::add_optional_header2(&self.consistency_level, request)?; + pub fn into_future(self) -> DeletePermission { + Box::pin(async move { + let mut request = self + .client + .prepare_request_with_permission_name(http::Method::DELETE); - Ok(()) + azure_core::headers::add_optional_header2(&self.consistency_level, &mut request)?; + + let response = self + .client + .pipeline() + .send( + self.context.clone().insert(ResourceType::Permissions), + &mut request, + ) + .await?; + + Ok(DeletePermissionResponse::try_from(response).await?) + }) + } +} + +type DeletePermission = + futures::future::BoxFuture<'static, crate::Result>; + +#[cfg(feature = "into_future")] +impl std::future::IntoFuture for DeletePermissionBuilder { + type Future = DeletePermission; + type Output = ::Output; + fn into_future(self) -> Self::Future { + Self::into_future(self) } } From 19927240b24ea731d74f78f26b20cf66b8c3d654 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 25 Feb 2022 09:13:42 +0100 Subject: [PATCH 10/13] Run format --- sdk/data_cosmos/examples/user_00.rs | 5 +---- sdk/data_cosmos/src/operations/create_permission.rs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sdk/data_cosmos/examples/user_00.rs b/sdk/data_cosmos/examples/user_00.rs index 0beda165d2..b0c82f0316 100644 --- a/sdk/data_cosmos/examples/user_00.rs +++ b/sdk/data_cosmos/examples/user_00.rs @@ -29,10 +29,7 @@ async fn main() -> Result<(), Box> { let database_client = client.into_database_client(database_name); let user_client = database_client.clone().into_user_client(user_name.clone()); - let create_user_response = user_client - .create_user() - .into_future() - .await?; + let create_user_response = user_client.create_user().into_future().await?; println!("create_user_response == {:#?}", create_user_response); let users = Box::pin(database_client.list_users(Context::new(), ListUsersOptions::new())) diff --git a/sdk/data_cosmos/src/operations/create_permission.rs b/sdk/data_cosmos/src/operations/create_permission.rs index 3be9a52bcd..c4c7a393f0 100644 --- a/sdk/data_cosmos/src/operations/create_permission.rs +++ b/sdk/data_cosmos/src/operations/create_permission.rs @@ -81,4 +81,4 @@ impl std::future::IntoFuture for CreatePermissionBuilder { fn into_future(self) -> Self::Future { Self::into_future(self) } -} \ No newline at end of file +} From b7840401ccdd81afa4d438e00bcc65811adee42f Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 25 Feb 2022 09:16:02 +0100 Subject: [PATCH 11/13] Run clippy --- sdk/data_cosmos/src/operations/create_collection.rs | 2 +- sdk/data_cosmos/src/operations/create_document.rs | 2 +- sdk/data_cosmos/src/operations/create_permission.rs | 4 ++-- sdk/data_cosmos/src/operations/create_user.rs | 2 +- sdk/data_cosmos/src/operations/delete_collection.rs | 2 +- sdk/data_cosmos/src/operations/delete_database.rs | 2 +- sdk/data_cosmos/src/operations/delete_document.rs | 2 +- sdk/data_cosmos/src/operations/delete_permission.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sdk/data_cosmos/src/operations/create_collection.rs b/sdk/data_cosmos/src/operations/create_collection.rs index 5daa95087e..c4a02de6b2 100644 --- a/sdk/data_cosmos/src/operations/create_collection.rs +++ b/sdk/data_cosmos/src/operations/create_collection.rs @@ -66,7 +66,7 @@ impl CreateCollectionBuilder { ) .await?; - Ok(CreateCollectionResponse::try_from(response).await?) + CreateCollectionResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/create_document.rs b/sdk/data_cosmos/src/operations/create_document.rs index 8d6a755748..ca315c188b 100644 --- a/sdk/data_cosmos/src/operations/create_document.rs +++ b/sdk/data_cosmos/src/operations/create_document.rs @@ -88,7 +88,7 @@ impl CreateDocumentBuilder { ) .await?; - Ok(CreateDocumentResponse::try_from(response).await?) + CreateDocumentResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/create_permission.rs b/sdk/data_cosmos/src/operations/create_permission.rs index c4c7a393f0..ff80e3547e 100644 --- a/sdk/data_cosmos/src/operations/create_permission.rs +++ b/sdk/data_cosmos/src/operations/create_permission.rs @@ -52,7 +52,7 @@ impl CreatePermissionBuilder { } let request_body = RequestBody { - id: &self.client.permission_name(), + id: self.client.permission_name(), permission_mode: self.permission_mode.kind(), resource: self.permission_mode.resource(), }; @@ -67,7 +67,7 @@ impl CreatePermissionBuilder { ) .await?; - Ok(PermissionResponse::try_from(response).await?) + PermissionResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/create_user.rs b/sdk/data_cosmos/src/operations/create_user.rs index d67389771e..0e16bd8fab 100644 --- a/sdk/data_cosmos/src/operations/create_user.rs +++ b/sdk/data_cosmos/src/operations/create_user.rs @@ -46,7 +46,7 @@ impl CreateUserBuilder { ) .await?; - Ok(UserResponse::try_from(response).await?) + UserResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/delete_collection.rs b/sdk/data_cosmos/src/operations/delete_collection.rs index f58b8df1fc..df1e53c93e 100644 --- a/sdk/data_cosmos/src/operations/delete_collection.rs +++ b/sdk/data_cosmos/src/operations/delete_collection.rs @@ -42,7 +42,7 @@ impl DeleteCollectionBuilder { ) .await?; - Ok(DeleteCollectionResponse::try_from(response).await?) + DeleteCollectionResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/delete_database.rs b/sdk/data_cosmos/src/operations/delete_database.rs index f48e537722..ba3cf58670 100644 --- a/sdk/data_cosmos/src/operations/delete_database.rs +++ b/sdk/data_cosmos/src/operations/delete_database.rs @@ -43,7 +43,7 @@ impl DeleteDatabaseBuilder { ) .await?; - Ok(DeleteDatabaseResponse::try_from(response).await?) + DeleteDatabaseResponse::try_from(response).await }) } } diff --git a/sdk/data_cosmos/src/operations/delete_document.rs b/sdk/data_cosmos/src/operations/delete_document.rs index f9da6ddcf7..9078a63298 100644 --- a/sdk/data_cosmos/src/operations/delete_document.rs +++ b/sdk/data_cosmos/src/operations/delete_document.rs @@ -48,7 +48,7 @@ impl DeleteDocumentBuilder { azure_core::headers::add_mandatory_header2(&self.allow_tentative_writes, &mut request)?; crate::cosmos_entity::add_as_partition_key_header_serialized2( - &self.client.partition_key_serialized(), + self.client.partition_key_serialized(), &mut request, ); diff --git a/sdk/data_cosmos/src/operations/delete_permission.rs b/sdk/data_cosmos/src/operations/delete_permission.rs index a170cfd767..a40a9f9caf 100644 --- a/sdk/data_cosmos/src/operations/delete_permission.rs +++ b/sdk/data_cosmos/src/operations/delete_permission.rs @@ -43,7 +43,7 @@ impl DeletePermissionBuilder { ) .await?; - Ok(DeletePermissionResponse::try_from(response).await?) + DeletePermissionResponse::try_from(response).await }) } } From fa4e8a8538a4c0a89f1cc1250b4d35b8d1892962 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 25 Feb 2022 09:47:55 +0100 Subject: [PATCH 12/13] Fix e2e tests --- sdk/data_cosmos/tests/attachment_00.rs | 35 +++++---- sdk/data_cosmos/tests/cosmos_collection.rs | 25 +++---- sdk/data_cosmos/tests/cosmos_database.rs | 3 +- sdk/data_cosmos/tests/cosmos_document.rs | 59 ++++++++------- sdk/data_cosmos/tests/permission.rs | 37 ++++------ .../tests/permission_token_usage.rs | 71 ++++++++----------- sdk/data_cosmos/tests/trigger.rs | 12 +--- sdk/data_cosmos/tests/user.rs | 8 +-- .../tests/user_defined_function00.rs | 12 +--- 9 files changed, 114 insertions(+), 148 deletions(-) diff --git a/sdk/data_cosmos/tests/attachment_00.rs b/sdk/data_cosmos/tests/attachment_00.rs index 147ab6700b..e9a98589f0 100644 --- a/sdk/data_cosmos/tests/attachment_00.rs +++ b/sdk/data_cosmos/tests/attachment_00.rs @@ -1,8 +1,6 @@ #![cfg(all(test, feature = "test_e2e"))] -use azure_core::Context; use azure_data_cosmos::prelude::*; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; mod setup; @@ -13,18 +11,18 @@ mod setup; // We do not need to define the "id" field here, it will be // specified in the Document struct below. #[derive(Serialize, Deserialize, Clone, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, - a_string: Cow<'a, str>, +struct MySampleStruct { + id: String, + a_string: String, a_number: u64, a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -64,11 +62,11 @@ async fn attachment() -> Result<(), azure_data_cosmos::Error> { excluded_paths: vec![], }; - let options = CreateCollectionOptions::new("/id") - .offer(Offer::Throughput(400)) - .indexing_policy(ip); database_client - .create_collection(Context::new(), COLLECTION_NAME, options) + .create_collection(COLLECTION_NAME, "/id") + .offer(Offer::Throughput(400)) + .indexing_policy(ip) + .into_future() .await .unwrap() }; @@ -80,15 +78,16 @@ async fn attachment() -> Result<(), azure_data_cosmos::Error> { let id = format!("unique_id{}", 100); let doc = MySampleStruct { - id: Cow::Borrowed(&id), - a_string: Cow::Borrowed("Something here"), + id: id.clone(), + a_string: "Something here".into(), a_number: 100, a_timestamp: chrono::Utc::now().timestamp(), }; // let's add an entity. let session_token: ConsistencyLevel = collection_client - .create_document(Context::new(), &doc, CreateDocumentOptions::new()) + .create_document(doc.clone()) + .into_future() .await? .into(); @@ -175,9 +174,7 @@ async fn attachment() -> Result<(), azure_data_cosmos::Error> { assert_eq!(1, ret.attachments.len()); // delete the database - database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) - .await?; + database_client.delete_database().into_future().await?; Ok(()) } diff --git a/sdk/data_cosmos/tests/cosmos_collection.rs b/sdk/data_cosmos/tests/cosmos_collection.rs index 9d3824df88..880ed8b913 100644 --- a/sdk/data_cosmos/tests/cosmos_collection.rs +++ b/sdk/data_cosmos/tests/cosmos_collection.rs @@ -23,11 +23,8 @@ async fn create_and_delete_collection() { // create a new collection let collection = database_client - .create_collection( - Context::new(), - COLLECTION_NAME, - CreateCollectionOptions::new("/id"), - ) + .create_collection(COLLECTION_NAME, "/id") + .into_future() .await .unwrap(); let collections = @@ -58,7 +55,8 @@ async fn create_and_delete_collection() { // delete the collection collection_client - .delete_collection(Context::new(), DeleteCollectionOptions::new()) + .delete_collection() + .into_future() .await .unwrap(); let collections = @@ -70,7 +68,8 @@ async fn create_and_delete_collection() { assert!(collections.collections.len() == 0); database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } @@ -96,11 +95,12 @@ async fn replace_collection() { included_paths: vec![], excluded_paths: vec![], }; - let options = CreateCollectionOptions::new("/id") - .offer(Offer::S2) - .indexing_policy(indexing_policy); + let collection = database_client - .create_collection(Context::new(), COLLECTION_NAME, options) + .create_collection(COLLECTION_NAME, "/id") + .offer(Offer::S2) + .indexing_policy(indexing_policy) + .into_future() .await .unwrap(); @@ -167,7 +167,8 @@ async fn replace_collection() { assert!(eps.len() > 0); database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } diff --git a/sdk/data_cosmos/tests/cosmos_database.rs b/sdk/data_cosmos/tests/cosmos_database.rs index c1846d0d74..25a9f6b679 100644 --- a/sdk/data_cosmos/tests/cosmos_database.rs +++ b/sdk/data_cosmos/tests/cosmos_database.rs @@ -48,7 +48,8 @@ async fn create_and_delete_database() { client .clone() .into_database_client(DATABASE_NAME) - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); diff --git a/sdk/data_cosmos/tests/cosmos_document.rs b/sdk/data_cosmos/tests/cosmos_document.rs index cef3085f81..7154dc9b60 100644 --- a/sdk/data_cosmos/tests/cosmos_document.rs +++ b/sdk/data_cosmos/tests/cosmos_document.rs @@ -1,8 +1,6 @@ #![cfg(all(test, feature = "test_e2e"))] use azure_core::Context; -use azure_data_cosmos::prelude::{ - CreateDocumentBuilder, DeleteDatabaseBuilder, GetDocumentOptions, -}; +use azure_data_cosmos::prelude::GetDocumentOptions; use serde::{Deserialize, Serialize}; mod setup; @@ -11,17 +9,17 @@ use azure_core::prelude::*; use azure_data_cosmos::prelude::*; use collection::*; -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] struct MyDocument { id: String, hello: u32, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MyDocument { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MyDocument { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -49,11 +47,11 @@ async fn create_and_delete_document() { excluded_paths: vec![], }; - let options = CreateCollectionOptions::new("/id") - .offer(Offer::Throughput(400)) - .indexing_policy(indexing_policy); database_client - .create_collection(Context::new(), COLLECTION_NAME, options) + .create_collection(COLLECTION_NAME, "/id") + .offer(Offer::Throughput(400)) + .indexing_policy(indexing_policy) + .into_future() .await .unwrap(); @@ -67,7 +65,8 @@ async fn create_and_delete_document() { hello: 42, }; collection_client - .create_document(Context::new(), &document_data, CreateDocumentOptions::new()) + .create_document(document_data.clone()) + .into_future() .await .unwrap(); @@ -98,7 +97,8 @@ async fn create_and_delete_document() { // delete document document_client - .delete_document(Context::new(), DeleteDocumentOptions::new()) + .delete_document() + .into_future() .await .unwrap(); @@ -111,7 +111,8 @@ async fn create_and_delete_document() { assert!(documents.len() == 0); database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } @@ -139,11 +140,11 @@ async fn query_documents() { excluded_paths: vec![], }; - let options = CreateCollectionOptions::new("/id") - .indexing_policy(indexing_policy) - .offer(Offer::S2); database_client - .create_collection(Context::new(), COLLECTION_NAME, options) + .create_collection(COLLECTION_NAME, "/id") + .indexing_policy(indexing_policy) + .offer(Offer::S2) + .into_future() .await .unwrap(); @@ -157,7 +158,8 @@ async fn query_documents() { hello: 42, }; collection_client - .create_document(Context::new(), &document_data, CreateDocumentOptions::new()) + .create_document(document_data.clone()) + .into_future() .await .unwrap(); @@ -185,7 +187,8 @@ async fn query_documents() { assert_eq!(query_result[0].result, document_data); database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } @@ -213,11 +216,11 @@ async fn replace_document() { excluded_paths: vec![], }; - let options = CreateCollectionOptions::new("/id") - .indexing_policy(indexing_policy) - .offer(Offer::S2); database_client - .create_collection(Context::new(), COLLECTION_NAME, options) + .create_collection(COLLECTION_NAME, "/id") + .indexing_policy(indexing_policy) + .offer(Offer::S2) + .into_future() .await .unwrap(); @@ -231,7 +234,8 @@ async fn replace_document() { hello: 42, }; collection_client - .create_document(Context::new(), &document_data, CreateDocumentOptions::new()) + .create_document(document_data.clone()) + .into_future() .await .unwrap(); @@ -279,7 +283,8 @@ async fn replace_document() { } database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } diff --git a/sdk/data_cosmos/tests/permission.rs b/sdk/data_cosmos/tests/permission.rs index 71478ddc6c..b7d2989914 100644 --- a/sdk/data_cosmos/tests/permission.rs +++ b/sdk/data_cosmos/tests/permission.rs @@ -1,5 +1,4 @@ #![cfg(all(test, feature = "test_e2e"))] -use azure_core::Context; use azure_data_cosmos::prelude::*; mod setup; @@ -26,23 +25,14 @@ async fn permissions() { // create two users let user1_client = database_client.clone().into_user_client(USER_NAME1); - let _create_user_response = user1_client - .create_user(Context::new(), CreateUserOptions::new()) - .await - .unwrap(); + let _create_user_response = user1_client.create_user().into_future().await.unwrap(); let user2_client = database_client.clone().into_user_client(USER_NAME2); - let _create_user_response = user2_client - .create_user(Context::new(), CreateUserOptions::new()) - .await - .unwrap(); + let _create_user_response = user2_client.create_user().into_future().await.unwrap(); // create a temp collection let create_collection_response = database_client - .create_collection( - Context::new(), - COLLECTION_NAME, - CreateCollectionOptions::new("/id"), - ) + .create_collection(COLLECTION_NAME, "/id") + .into_future() .await .unwrap(); @@ -51,20 +41,16 @@ async fn permissions() { let permission_client_user2 = user2_client.clone().into_permission_client(PERMISSION2); let _create_permission_user1_response = permission_client_user1 - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &create_collection_response.collection.all_permission(), - ) + .create_permission(create_collection_response.collection.all_permission()) + .expiry_seconds(18000u64) // 5 hours, max! + .into_future() .await .unwrap(); let _create_permission_user2_response = permission_client_user2 - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &create_collection_response.collection.read_permission(), - ) + .create_permission(create_collection_response.collection.read_permission()) + .expiry_seconds(18000u64) // 5 hours, max! + .into_future() .await .unwrap(); @@ -76,7 +62,8 @@ async fn permissions() { // delete the database database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } diff --git a/sdk/data_cosmos/tests/permission_token_usage.rs b/sdk/data_cosmos/tests/permission_token_usage.rs index 5212406c68..5abf89fd20 100644 --- a/sdk/data_cosmos/tests/permission_token_usage.rs +++ b/sdk/data_cosmos/tests/permission_token_usage.rs @@ -1,24 +1,22 @@ #![cfg(all(test, feature = "test_e2e"))] -use azure_core::Context; use azure_data_cosmos::prelude::*; use collection::*; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; mod setup; #[derive(Clone, Serialize, Deserialize, Debug)] -struct MySampleStruct<'a> { - id: Cow<'a, str>, +struct MySampleStruct { + id: String, age: u32, - phones: Vec>, + phones: Vec, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct<'a> { - type Entity = &'a str; +impl azure_data_cosmos::CosmosEntity for MySampleStruct { + type Entity = String; - fn partition_key(&'a self) -> Self::Entity { - self.id.as_ref() + fn partition_key(&self) -> Self::Entity { + self.id.clone() } } @@ -48,30 +46,25 @@ async fn permission_token_usage() { excluded_paths: vec![], }; - let create_collection_options = CreateCollectionOptions::new("/id") - .offer(Offer::Throughput(400)) - .indexing_policy(indexing_policy); let create_collection_response = database_client - .create_collection(Context::new(), COLLECTION_NAME, create_collection_options) + .create_collection(COLLECTION_NAME, "/id") + .offer(Offer::Throughput(400)) + .indexing_policy(indexing_policy) + .into_future() .await .unwrap(); let user_client = database_client.clone().into_user_client(USER_NAME); - user_client - .create_user(Context::new(), CreateUserOptions::new()) - .await - .unwrap(); + user_client.create_user().into_future().await.unwrap(); // create the RO permission let permission_client = user_client.into_permission_client(PERMISSION); let permission_mode = create_collection_response.collection.read_permission(); let create_permission_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &permission_mode, - ) + .create_permission(permission_mode) + .expiry_seconds(18000u64) // 5 hours, max! + .into_future() .await .unwrap(); @@ -99,33 +92,30 @@ async fn permission_token_usage() { // Now we try to insert a document with the "read-only" // authorization_token just created. It must fail. let document = MySampleStruct { - id: Cow::Borrowed("Gianluigi Bombatomica"), + id: "Gianluigi Bombatomica".into(), age: 43, - phones: vec![Cow::Borrowed("+39 1234567"), Cow::Borrowed("+39 2345678")], + phones: vec!["+39 1234567".into(), "+39 2345678".into()], }; new_collection_client - .create_document( - Context::new(), - &document, - CreateDocumentOptions::new().is_upsert(true), - ) + .create_document(document.clone()) + .is_upsert(true) + .into_future() .await .unwrap_err(); permission_client - .delete_permission(Context::new(), DeletePermissionOptions::new()) + .delete_permission() + .into_future() .await .unwrap(); // All includes read and write. let permission_mode = create_collection_response.collection.all_permission(); let create_permission_response = permission_client - .create_permission( - Context::new(), - CreatePermissionOptions::new().expiry_seconds(18000u64), // 5 hours, max! - &permission_mode, - ) + .create_permission(permission_mode) + .expiry_seconds(18000u64) // 5 hours, max! + .into_future() .await .unwrap(); @@ -140,11 +130,9 @@ async fn permission_token_usage() { // now we have an "All" authorization_token // so the create_document should succeed! let create_document_response = new_collection_client - .create_document( - Context::new(), - &document, - CreateDocumentOptions::new().is_upsert(true), - ) + .create_document(document) + .is_upsert(true) + .into_future() .await .unwrap(); println!( @@ -154,7 +142,8 @@ async fn permission_token_usage() { // cleanup database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); } diff --git a/sdk/data_cosmos/tests/trigger.rs b/sdk/data_cosmos/tests/trigger.rs index 3c680e93d1..090ec58bd8 100644 --- a/sdk/data_cosmos/tests/trigger.rs +++ b/sdk/data_cosmos/tests/trigger.rs @@ -1,5 +1,4 @@ #![cfg(all(test, feature = "test_e2e"))] -use azure_core::prelude::*; use azure_data_cosmos::prelude::*; use futures::stream::StreamExt; @@ -55,11 +54,8 @@ async fn trigger() -> Result<(), azure_data_cosmos::Error> { // create a temp collection let _create_collection_response = { database_client - .create_collection( - Context::new(), - COLLECTION_NAME, - CreateCollectionOptions::new("/id"), - ) + .create_collection(COLLECTION_NAME, "/id") + .into_future() .await .unwrap() }; @@ -107,9 +103,7 @@ async fn trigger() -> Result<(), azure_data_cosmos::Error> { .await?; // delete the database - database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) - .await?; + database_client.delete_database().into_future().await?; Ok(()) } diff --git a/sdk/data_cosmos/tests/user.rs b/sdk/data_cosmos/tests/user.rs index c1fcd0142f..a4456f7050 100644 --- a/sdk/data_cosmos/tests/user.rs +++ b/sdk/data_cosmos/tests/user.rs @@ -32,10 +32,7 @@ async fn users() { let database_client = client.clone().into_database_client(DATABASE_NAME); let user_client = database_client.clone().into_user_client(USER_NAME); - let _create_user_response = user_client - .create_user(Context::new(), CreateUserOptions::new()) - .await - .unwrap(); + let _create_user_response = user_client.create_user().into_future().await.unwrap(); let list_users_response = Box::pin(database_client.list_users(Context::new(), ListUsersOptions::new())) @@ -89,7 +86,8 @@ async fn users() { client .clone() .into_database_client(DATABASE_NAME) - .delete_database(Context::new(), DeleteDatabaseOptions::new()) + .delete_database() + .into_future() .await .unwrap(); diff --git a/sdk/data_cosmos/tests/user_defined_function00.rs b/sdk/data_cosmos/tests/user_defined_function00.rs index 55aa178561..97ec67bda9 100644 --- a/sdk/data_cosmos/tests/user_defined_function00.rs +++ b/sdk/data_cosmos/tests/user_defined_function00.rs @@ -1,5 +1,4 @@ #![cfg(all(test, feature = "test_e2e"))] -use azure_core::prelude::*; use azure_data_cosmos::prelude::*; use azure_data_cosmos::responses::QueryDocumentsResponseRaw; use futures::stream::StreamExt; @@ -37,11 +36,8 @@ async fn user_defined_function00() -> Result<(), azure_data_cosmos::Error> { // create a temp collection let _create_collection_response = database_client - .create_collection( - Context::new(), - COLLECTION_NAME, - CreateCollectionOptions::new("/id"), - ) + .create_collection(COLLECTION_NAME, "/id") + .into_future() .await .unwrap(); @@ -117,9 +113,7 @@ async fn user_defined_function00() -> Result<(), azure_data_cosmos::Error> { .await?; // delete the database - database_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) - .await?; + database_client.delete_database().into_future().await?; Ok(()) } From 10a982b0be8ce3ba690492d01311aa0e1e4036a3 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 25 Feb 2022 10:02:32 +0100 Subject: [PATCH 13/13] Fix local tests --- sdk/data_cosmos/src/lib.rs | 12 +++++------- sdk/data_cosmos/tests/collection_operations.rs | 16 ++++------------ .../tests/create_database_and_collection.rs | 11 +++-------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/sdk/data_cosmos/src/lib.rs b/sdk/data_cosmos/src/lib.rs index 201ae4d2ae..9849eabc27 100644 --- a/sdk/data_cosmos/src/lib.rs +++ b/sdk/data_cosmos/src/lib.rs @@ -30,10 +30,10 @@ struct MySampleStruct { a_timestamp: i64, } -impl<'a> azure_data_cosmos::CosmosEntity<'a> for MySampleStruct { +impl azure_data_cosmos::CosmosEntity for MySampleStruct { type Entity = u64; - fn partition_key(&'a self) -> Self::Entity { + fn partition_key(&self) -> Self::Entity { self.a_number } } @@ -81,11 +81,9 @@ async fn main() -> Result<(), Box> { // insert it collection_client - .create_document( - Context::new(), - &document_to_insert, - CreateDocumentOptions::new().is_upsert(true), - ) + .create_document(document_to_insert) + .is_upsert(true) + .into_future() .await?; } // wow that was easy and fast, wasn't it? :) diff --git a/sdk/data_cosmos/tests/collection_operations.rs b/sdk/data_cosmos/tests/collection_operations.rs index 54bead1865..b42a6d9e07 100644 --- a/sdk/data_cosmos/tests/collection_operations.rs +++ b/sdk/data_cosmos/tests/collection_operations.rs @@ -26,11 +26,8 @@ async fn collection_operations() -> Result<(), BoxedError> { log::info!("Creating a collection with name '{}'...", collection_name); let create_collection_response = db_client - .create_collection( - context.clone(), - collection_name, - CreateCollectionOptions::new("/id"), - ) + .create_collection(collection_name, "/id") + .into_future() .await?; assert_eq!(create_collection_response.collection.id, collection_name); @@ -112,9 +109,7 @@ async fn collection_operations() -> Result<(), BoxedError> { ); // delete collection! - let delete_collection_response = collection_client - .delete_collection(context.clone(), DeleteCollectionOptions::new()) - .await?; + let delete_collection_response = collection_client.delete_collection().into_future().await?; log::info!("Successfully deleted collection"); log::debug!( @@ -122,10 +117,7 @@ async fn collection_operations() -> Result<(), BoxedError> { delete_collection_response ); - db_client - .delete_database(Context::new(), DeleteDatabaseOptions::new()) - .await - .unwrap(); + db_client.delete_database().into_future().await.unwrap(); Ok(()) } diff --git a/sdk/data_cosmos/tests/create_database_and_collection.rs b/sdk/data_cosmos/tests/create_database_and_collection.rs index 559ee3c655..b84948754e 100644 --- a/sdk/data_cosmos/tests/create_database_and_collection.rs +++ b/sdk/data_cosmos/tests/create_database_and_collection.rs @@ -30,11 +30,8 @@ async fn create_database_and_collection() -> Result<(), BoxedError> { let collection_name = "panzadoro"; log::info!("Creating a collection with name '{}'...", collection_name); let collection = db_client - .create_collection( - context.clone(), - collection_name, - CreateCollectionOptions::new("/id"), - ) + .create_collection(collection_name, "/id") + .into_future() .await?; assert_eq!(collection.collection.id, collection_name); log::info!("Successfully created a collection"); @@ -53,9 +50,7 @@ async fn create_database_and_collection() -> Result<(), BoxedError> { // delete database log::info!("Deleting the database..."); - let deleted_database = db_client - .delete_database(context.clone(), DeleteDatabaseOptions::new()) - .await?; + let deleted_database = db_client.delete_database().into_future().await?; log::info!("Successfully deleted database"); log::debug!("The delete_database response: {:#?}", deleted_database);