use reqwest::multipart;
use std::path::{Path, PathBuf};
pub fn file_part_from_path(path: &Path) -> Result<multipart::Part, std::io::Error> {
let file_name = path
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("file")
.to_string();
let bytes = std::fs::read(path)?;
let part = multipart::Part::bytes(bytes).file_name(file_name);
Ok(part)
}
#[allow(dead_code)]
pub fn file_part_from_pathbuf(path: PathBuf) -> Result<multipart::Part, std::io::Error> {
file_part_from_path(&path)
}
#[allow(dead_code)]
pub fn file_part_from_bytes(bytes: Vec<u8>, filename: String) -> multipart::Part {
multipart::Part::bytes(bytes).file_name(filename)
}
pub fn add_file_to_form(
form: multipart::Form,
path: &Path,
field_name: &str,
) -> Result<multipart::Form, std::io::Error> {
let part = file_part_from_path(path)?;
Ok(form.part(field_name.to_string(), part))
}
#[allow(dead_code)]
pub fn add_pathbuf_to_form(
form: multipart::Form,
path: PathBuf,
field_name: &str,
) -> Result<multipart::Form, std::io::Error> {
add_file_to_form(form, &path, field_name)
}
pub fn add_schema_value_to_form(
form: multipart::Form,
field_name: &str,
value: serde_json::Value,
content_type: Option<&str>,
) -> Result<multipart::Form, reqwest::Error> {
let default_json = matches!(
&value,
serde_json::Value::Object(_) | serde_json::Value::Array(_)
);
let explicit_json = content_type.is_some_and(|media_type| {
media_type
.split(';')
.next()
.is_some_and(|essence| essence.trim().eq_ignore_ascii_case("application/json"))
});
let body = if default_json || explicit_json {
value.to_string()
} else {
match value {
serde_json::Value::String(text) => text,
other => other.to_string(),
}
};
let media_type = content_type.or_else(|| default_json.then_some("application/json"));
let part = match media_type {
Some(media_type) => multipart::Part::text(body).mime_str(media_type)?,
None => multipart::Part::text(body),
};
Ok(form.part(field_name.to_string(), part))
}