0

我正在用这个例子学习 Rust 和 Rusoto https://www.rusoto.org/futures.html 我发现许多代码已经过时了。所以我改变了这样的代码:

use rusoto_core::{Region, RusotoError};
use rusoto_dynamodb::{
    AttributeDefinition, AttributeValue, CreateTableError, CreateTableInput, CreateTableOutput,
    DynamoDb, DynamoDbClient, GetItemError, GetItemInput, GetItemOutput, KeySchemaElement,
    UpdateItemError, UpdateItemInput, UpdateItemOutput,
};
use std::collections::HashMap;
use std::error::Error;
use tokio_core::reactor::Core;

fn main() {
    let item = make_item();
    let client = get_dynamodb_local_client();
    let mut core = Core::new().unwrap();

    let chained_future = chain_futures(&client, &item);

    let item_from_dynamo = match core.run(chained_future) {
        Ok(item) => item,
        Err(e) => panic!("Error completing futures: {}", e),
    };
    println!("item: {:?}", item_from_dynamo);
}

async fn chain_futures(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> Result<GetItemOutput, RusotoError<impl Error>> {
    let _ = make_create_table_future(client).await;
    let _ = make_upsert_item_future(client, item).await;
    make_get_item_future(client, item).await
}

async fn make_create_table_future(
    client: &DynamoDbClient,
) -> Result<CreateTableOutput, RusotoError<CreateTableError>> {
    let attribute_def = AttributeDefinition {
        attribute_name: "foo_name".to_string(),
        attribute_type: "S".to_string(),
    };
    let k_schema = KeySchemaElement {
        attribute_name: "foo_name".to_string(),
        key_type: "HASH".to_string(), // case sensitive
    };
    let make_table_request = CreateTableInput {
        table_name: "a-testing-table".to_string(),
        attribute_definitions: vec![attribute_def],
        key_schema: vec![k_schema],
        ..Default::default()
    };
    client.create_table(make_table_request).await
}

async fn make_upsert_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> Result<UpdateItemOutput, RusotoError<UpdateItemError>> {
    let add_item = UpdateItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };

    client.update_item(add_item).await
}

async fn make_get_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> Result<GetItemOutput, RusotoError<GetItemError>> {
    // future for getting the entry
    let get_item_request = GetItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };
    client.get_item(get_item_request).await
}

fn make_item() -> HashMap<String, AttributeValue> {
    let item_key = "foo_name";
    let mut item = HashMap::new();
    item.insert(
        item_key.to_string(),
        AttributeValue {
            s: Some("baz".to_string()),
            ..Default::default()
        },
    );

    item
}

fn get_dynamodb_local_client() -> DynamoDbClient {
    // Create custom Region
    let region = Region::Custom {
        name: "us-east-1".to_owned(),
        endpoint: "http://localhost:8000".to_owned(),
    };

    DynamoDbClient::new(region)
}

然后我发现了这个编译错误:

error[E0277]: the trait bound `impl std::future::Future: futures::future::Future` is not satisfied
  --> cmd/src/main.rs:18:43
   |
18 |     let item_from_dynamo = match core.run(chained_future) {
   |                                           ^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `impl std::future::Future`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `cmd`.

To learn more, run the command again with --verbose.
make: *** [run] Error 101

谁能解释这个错误?这两个未来特征有什么区别?代码应该是什么样的?

这是我的货物依赖项:

[dependencies]
rusoto_core = "0.44"
rusoto_dynamodb = "0.44"
futures = "0.3"
tokio = { version = "0.2", features = ["full"] }
tokio-core = "0.1"

谢谢

布鲁斯

4

1 回答 1

0

Instead of using tokio_core::reactor::Core, I used tokio::runtime::Runtime and block_on

Working code:


extern crate futures;
extern crate rusoto_core;
extern crate rusoto_dynamodb;
extern crate tokio_core;

use futures::future::FutureExt;
use rusoto_core::{Region, RusotoError};
use rusoto_dynamodb::{
    AttributeDefinition, AttributeValue, CreateTableError, CreateTableInput, CreateTableOutput,
    DynamoDb, DynamoDbClient, GetItemError, GetItemInput, GetItemOutput, KeySchemaElement,
    UpdateItemError, UpdateItemInput, UpdateItemOutput,
};
use std::collections::HashMap;

fn main() {
    let item = make_item();
    let client = get_dynamodb_local_client();
    let mut core = tokio::runtime::Runtime::new().unwrap();

    let create_table_future = make_create_table_future(&client);
    let upsert_item_future = make_upsert_item_future(&client, &item);
    let item_from_dynamo_future = make_get_item_future(&client, &item);

    let chained_futures = create_table_future
        .then(|_| upsert_item_future)
        .then(|_| item_from_dynamo_future);

    let item_from_dynamo = match core.block_on(chained_futures) {
        Ok(item) => item,
        Err(e) => panic!("Error completing futures: {}", e),
    };
    println!("item: {:?}", item_from_dynamo);
}

async fn make_create_table_future(
    client: &DynamoDbClient,
) -> Result<CreateTableOutput, RusotoError<CreateTableError>> {
    let attribute_def = AttributeDefinition {
        attribute_name: "foo_name".to_string(),
        attribute_type: "S".to_string(),
    };
    let k_schema = KeySchemaElement {
        attribute_name: "foo_name".to_string(),
        key_type: "HASH".to_string(), // case sensitive
    };
    let make_table_request = CreateTableInput {
        table_name: "a-testing-table".to_string(),
        attribute_definitions: vec![attribute_def],
        key_schema: vec![k_schema],
        ..Default::default()
    };

    client.create_table(make_table_request).await
}

async fn make_upsert_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> Result<UpdateItemOutput, RusotoError<UpdateItemError>> {
    let add_item = UpdateItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };

    client.update_item(add_item).await
}

async fn make_get_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> Result<GetItemOutput, RusotoError<GetItemError>> {
    // future for getting the entry
    let get_item_request = GetItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };
    client.get_item(get_item_request).await
}

fn make_item() -> HashMap<String, AttributeValue> {
    let item_key = "foo_name";
    let mut item = HashMap::new();
    item.insert(
        item_key.to_string(),
        AttributeValue {
            s: Some("baz".to_string()),
            ..Default::default()
        },
    );

    item
}

fn get_dynamodb_local_client() -> DynamoDbClient {
    // Create custom Region
    let region = Region::Custom {
        name: "us-east-1".to_owned(),
        endpoint: "http://localhost:8000".to_owned(),
    };

    DynamoDbClient::new(region)
}


于 2020-12-18T14:31:35.930 回答