Repository: AmbientRun/Ambient
File: crates/deploy/src/lib.rs (Rust)

Code before:
}

impl FileRequest {
    fn path(&self) -> &str {
        match self {
            FileRequest::SendMD5(path) => path,
            FileRequest::SendContents(path) => path,
            FileRequest::Accepted(path) => path,
        }
    }
}

async fn process_file_requests(
    rx: flume::Receiver<FileRequest>,
    tx: flume::Sender<DeployAssetRequest>,
    ember_id: String,
    mut asset_path_to_file_path: HashMap<String, PathBuf>,
) -> anyhow::Result<()> {
    while let Ok(request) = rx.recv_async().await {
        // get file path
        let path = request.path();
        let Some(file_path) = asset_path_to_file_path.get(path) else {
            // we do a check here to prevent server from asking for files that it shouldn't ask for
            log::warn!("Unknown asset path: {:?}", path);
            continue;
        };

        match request {
            FileRequest::SendMD5(path) => {
                // send MD5 hash
                let content = ambient_sys::fs::read(file_path).await?;
                let md5_digest = md5::Md5::default()
                    .chain_update(&content)
                    .finalize()
                    .to_vec();
                log::debug!("Sending MD5 for {:?} = {}", path, hex(&md5_digest));
                tx.send_async(DeployAssetRequest {
                    ember_id: ember_id.clone(),
                    contents: vec![AssetContent {
                        path,
                        total_size: content.len() as u64,
                        content_description: Some(ContentDescription::Md5(md5_digest)),
                    }],
                })
                .await?;
            }
            FileRequest::SendContents(path) => {
                // send file contents
                log::debug!("Sending contents for {:?}", path);
                let requests = asset_requests_from_file_path(&ember_id, &path, file_path).await?;
                let count = requests.len();

Review comment (suggestion):
Same here regarding UTF-8.

I would prefer to use the appropriate type for the job, unless this is an encoded path, (in which case a newtype may be more clear)

Code after:
    };

    // set up the endpoint and connect
    let channel = {
        let mut endpoint = Channel::from_shared(api_server)?;
        if let Some(tls) = tls {
            endpoint = endpoint.tls_config(tls)?
        }
        endpoint.connect().await?
    };

    // set up client with auth token and compression
    let token: MetadataValue<_> = format!("Bearer {}", auth_token).parse()?;
    let client = DeployerClient::new(InterceptedService::new(channel, {
        move |mut req: Request<()>| {
            req.metadata_mut().insert("authorization", token.clone());
            Ok(req)
        }
    }))
    .send_compressed(CompressionEncoding::Gzip)
    .accept_compressed(CompressionEncoding::Gzip);
    Ok(client)
}

enum FileRequest {
    SendMD5(String),
    SendContents(String),
    Accepted(String),
}

impl FileRequest {
    fn path(&self) -> &str {
        match self {
            FileRequest::SendMD5(path) => path,
            FileRequest::SendContents(path) => path,
            FileRequest::Accepted(path) => path,
        }
    }
}

async fn process_file_requests(
    rx: flume::Receiver<FileRequest>,
    tx: flume::Sender<DeployAssetRequest>,
    ember_id: String,
    mut asset_path_to_file_path: HashMap<String, PathBuf>,
) -> anyhow::Result<()> {
    while let Ok(request) = rx.recv_async().await {
        // get file path
        let path = request.path();
        let Some(file_path) = asset_path_to_file_path.get(path) else {
            // we do a check here to prevent server from asking for files that it shouldn't ask for