Чтение Rusoto S3 StreamingBody в то, что Brotli может распаковать

Версия 0.32 StreamingBody от rusuto_s3, которая возвращается при запросе файла из AWS S3, больше не поддерживает Read.

До этой версии, brotli::BrotliDecompress(&mut &*would_like_to_pass_this, &mut contents); был способ, которым я получал бы данные из S3 и в содержание. Теперь это приводит к этому сообщению об ошибке:

ошибка [E0614]: тип rusoto_s3::StreamingBody не может быть разыменовано

Корректировка на brotli::BrotliDecompress(&mut would_like_to_pass_this, &mut contents); заставляет заявителя пожаловаться:

ошибка [E0277]: ограничение черты rusoto_s3::StreamingBody::std::io::Read не устраивает

черта std::io::Read не реализовано для rusoto_s3::StreamingBody

что требуется brotli::BrotliDecompress,

Поскольку StreamingBody должен реализовывать Stream в соответствии с документацией, я попытался собрать данные в Vec, используя let bytes = body.concat2().wait().unwrap();,

Тем не менее, это не удается:

error[E0599]: no method named `concat2` found for type `rusoto_s3::StreamingBody` in the current scope                
  --> src/ingest/mod.rs:64:34
   |
64 |                 let bytes = body.concat2().wait().unwrap();                                                      
   |                                  ^^^^^^^
   |
   = help: items from traits can only be used if the trait is in scope                                                
   = note: the following trait is implemented but not in scope, perhaps add a `use` for it:                           
           candidate #1: `use futures::stream::Stream;`

Как вы можете видеть в полном примере кода, предложение было добавлено без каких-либо других результатов.

use std::io::Cursor;

use futures::stream::Stream;
use rusoto_core::Region;
use rusoto_s3::{GetObjectRequest, S3, S3Client, StreamingBody};
use serde_json;

pub fn load_data_from_s3(folder_name: String) -> CustomObject {
    let client = S3Client::simple(Region::UsWest2);

    let mut custom_object = CustomObject::empty();

    // following a list of keys (~filenames) for S3
    ["key_name1", "key_name2"].iter().for_each(|key_name| {
        let request = GetObjectRequest {
            bucket: ("bigger_bucket/".to_owned() + &folder_name).to_string(),
            key: key_name.to_string(),
            ..Default::default()
        };
        if let Ok(file) = client.get_object(&request).sync() {
            // Calculate the content size by getting the current file size
            // multiplied by a factor of 3 for the decompression
            let initial_contents_size = match file.content_length {
                Some(data) => 3 * data as usize,
                _ => 0,
            };
            let mut contents = Cursor::new(Vec::with_capacity(initial_contents_size));

            /*
             *
             * Start of the problem area
             *
             */
            // BrotliDecompress needs to act on something with the Read trait implemented,
            // which isn't the case with StreamingBody anylonger
            let would_like_to_pass_this = file.body.unwrap();
            // trying to get a Vec<u8> here
            let bytes = would_like_to_pass_this.concat2().wait().unwrap();
            brotli::BrotliDecompress(&mut &*bytes, &mut contents);
            /*
             *
             * End of the problem area
             *
             */    

            // below code is for more context
            // Reset the cursor to the beginning so we can read the decompressed data
            contents.set_position(0);

            match *key_name {
                "key_name1" => custom_object
                    .do_stuff_with_key_name1_content(serde_json::from_reader(contents).unwrap()),
                "key_name2" => custom_object
                    .do_stuff_with_key_name2_content(serde_json::from_reader(contents).unwrap()),
                _ => {}
            }
        }
    });
    custom_object
}

0 ответов

Другие вопросы по тегам