pub type Result = std::result::Result<ft_sdk::chr::CHR<Output>, ft_sdk::Error>;
#[derive(Debug)]
pub enum Output {
Json(serde_json::Value),
Binary(Binary),
Redirect(String, http::HeaderValue),
}
#[derive(Debug)]
pub struct Binary {
pub file_name: Option<String>,
pub content: bytes::Bytes,
pub content_type: String,
}
pub(crate) fn binary_response(
binary: Binary,
) -> std::result::Result<::http::Response<bytes::Bytes>, ft_sdk::Error> {
let mut response_builder = http::Response::builder()
.status(200)
.header("Content-Type", binary.content_type.as_str());
if let Some(filename) = binary.file_name {
response_builder = response_builder.header(
"Content-Disposition",
format!("attachment; filename=\"{filename}\"").as_str(),
)
}
Ok(response_builder.body(binary.content)?)
}
impl From<ft_sdk::chr::CHR<Output>>
for std::result::Result<http::Response<bytes::Bytes>, ft_sdk::Error>
{
fn from(
ft_sdk::chr::CHR {
cookies,
headers,
response,
}: ft_sdk::chr::CHR<Output>,
) -> Self {
let response = match response {
Output::Json(json_value) => ft_sdk::json(json_value),
Output::Binary(binary) => binary_response(binary),
Output::Redirect(url, cookie) => Ok(http::Response::builder()
.status(200)
.header(http::header::SET_COOKIE, cookie)
.header(http::header::CONTENT_TYPE, "text/html; charset=utf-8")
.body(format!("<meta http-equiv='refresh' content='0; url={url}' />").into())?),
}?;
ft_sdk::chr::chr(cookies, headers, response)
}
}
pub fn download<S1: AsRef<str>, S2: AsRef<str>>(
file_name: S1,
content: bytes::Bytes,
content_type: S2,
) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Binary(Binary {
file_name: Some(file_name.as_ref().to_string()),
content,
content_type: content_type.as_ref().to_string(),
})))
}
pub fn binary<S: AsRef<str>>(content: bytes::Bytes, content_type: S) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Binary(Binary {
file_name: None,
content,
content_type: content_type.as_ref().to_string(),
})))
}
pub fn browser_redirect_with_cookie<S: AsRef<str>>(url: S, c: http::HeaderValue) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Redirect(
url.as_ref().to_string(),
c,
)))
}
pub fn json<T: serde::Serialize>(t: T) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Json(serde_json::to_value(
t,
)?)))
}
pub fn api_ok<T: serde::Serialize>(t: T) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Json(
serde_json::json!({"data": serde_json::to_value(t)?, "success": true }),
)))
}
pub fn api_error(errors: std::collections::HashMap<String, String>) -> Result {
Ok(ft_sdk::chr::CHR::new(Output::Json(
serde_json::json!({"errors": serde_json::to_value(errors)?, "success": false }),
)))
}