Stranger6667/jsonschema-rs

Async SchemaResolver

Opened this issue · 0 comments

I'm using an async S3 client to load schemas from a bucket. I've hit a wall in that SchemaResolver is not async, but I need to call an async method within it. Is AsyncSchemaResolver on the roadmap or is there a known work around?

///
/// Download an object from the S3 bucket and turn the result as Bytes
/// 
pub async fn download_object(client: &Client, bucket_name: &str, key: &str) -> Result<Bytes, S3Error> {
    let resp = client
        .get_object()
        .bucket(bucket_name)
        .key(key)
        .send()
        .await?;
    let data = match resp.body.collect().await {
        Ok(data) => data,
        Err(e) => return Err(S3Error::GetObjectError{ bucket_name: bucket_name.to_string(), key: key.to_string(), msg: e.to_string() }),
    };
    let data = data.into_bytes();

    Ok(data)
}

///
/// Download and object from the S3 bucket and return the results as a json Value
/// 
pub async fn download_json(client: &Client, bucket_name: &str, path: &str) -> Result<serde_json::Value, JsonError> {
    let data = download_object(client, bucket_name, path).await?;
    let json: serde_json::Value = serde_json::from_slice(&data)?;
    Ok(json)
}

struct S3SchemaResolver {
    client: Client,         // S3 client
    bucket_name: String     // name of bucket that holds schemas
}

impl SchemaResolver for S3SchemaResolver {
    fn resolve(&self, root_schema: &Value, url: &Url, original_reference: &str) -> Result<Arc<Value>, SchemaResolverError> {
        //
        // add the base path to the reference
        //
        match download_json(&self.client, &self.bucket_name, original_reference).await {
            Ok(schema_value) => Ok(Arc::new(schema_value)),
            Err(json_error) => {
                let msg = format!("{}", json_error);
                log::error!("{}", msg);
                Err(anyhow::anyhow!(msg))
            }
        }
    }
}