Search code examples
rustserverclientbsonserde

How do I convert a buffer into BSON format?


I'm trying to convert a file (that I opened and read into a buffer), into a valid BSON format.

I writing the client-side for making a request that takes two fields;

  1. Name of the file
  2. File(buffer)

The problem here is I can't seem to make a successful conversion here.

Another question is, after making this conversion, is it possible to convert this BSON request into a buffer, because that's the type curl(Easy) crate takes for making its requests (i.e requests that are from the terminal, not the browser of forms)

this is my code for making this request

// It takes in a file path.
fn send_file_post(file_from_arg: &str) -> tide::Result {

    // initialise the connection to the server
    let mut easy = Easy::new();
    easy.url("http://0.0.0.0:8080/hi").unwrap();

    // Opens and reads the file path
    let mut file = File::open(file_from_arg)?;
    let mut buf = [0; 1096];

    // reads file into buffer
    loop {
        let n = file.read(&mut buf)?;

        if n == 0 {
            // reached end of file
            break;
        }

        // easy.write_all(&buf[..n])?;
    }


// attempted bson format
    let bson_data: Bson = bson!({
    "name": file_from_arg,
    "file": buf
});

// sending the request, this is only sending the file for now, I want to send a bson format that is buffered (in a buffer/bytes format) 
    easy.post_fields_copy(&buf).unwrap();
    easy.write_function(|data| {
        stdout().write_all(data).unwrap();
        Ok(data.len())
    })
    .unwrap();

    println!(" oh hi{:?}", easy.perform().unwrap());
    Ok(format!("okay sent!").into())
}

Solution

  • I realised that serde_json has a convert to vec! method, which can be likened to bytes if not the same. So I converted the file into bytes and sent it as a buffer. This is what the function looks like below.

    
    // It takes in a file path.
    fn send_file_post(file_from_arg: &str, port_addr: &str) -> tide::Result {
        // initialise
        let mut easy = Easy::new();
        let port = format!("{}/hi", port_addr);
        easy.url(&port).unwrap();
        
    // reads file path
        let file = std::fs::read(file_from_arg)?;
    
    
        //extracts name of the file from file path
        let (.., file_name) = file_from_arg
            .rsplit_once(std::path::MAIN_SEPARATOR)
            .unwrap();
    
    // creates the necessary type to send the file in bytes
        let new_post = FileSearch {
            file_name: file_name.to_string(),
            file_bytes: file,
        };
    
    // Unwrap into a vector, which can be likened to bytes
        let send_file_body_req = serde_json::to_vec(&new_post).unwrap();
    
        // make and send request
        easy.post(true).unwrap();
        easy.post_field_size(send_file_body_req.len() as u64).unwrap();
    
        let mut transfer = easy.transfer();
        transfer
            .read_function(|buf| Ok(send_file_body_req.as_slice().read(buf).unwrap_or(0)))
            .unwrap();
        transfer.perform().unwrap();
    
        Ok(format!("okay sent!").into())
    }