Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
radicle-desktop crates radicle-types src source blob.rs
use base64::{prelude::BASE64_STANDARD, Engine};
use radicle::git::Oid;
use radicle_surf as surf;
use serde::Serialize;
use ts_rs::TS;

use crate::repo::Commit;
use crate::traits::repo::MAX_BLOB_SIZE;

#[derive(TS, Serialize)]
#[ts(export)]
#[ts(export_to = "source/")]
#[serde(rename_all = "camelCase")]
pub struct Blob {
    #[ts(as = "String")]
    id: Oid,
    binary: bool,
    commit: Commit,
    mime_type: String,
    content: String,
}

impl<T: AsRef<[u8]>> From<surf::blob::Blob<T>> for Blob {
    fn from(blob: surf::blob::Blob<T>) -> Self {
        let content = match blob.size() {
            s if s > MAX_BLOB_SIZE && blob.is_binary() => {
                String::from("Payload too large, content has been truncated")
            }
            _ => match std::str::from_utf8(blob.content()) {
                Ok(s) => s.to_owned(),
                Err(_) => BASE64_STANDARD.encode(blob.content()),
            },
        };

        let mime_type = infer::get(blob.content()).map(|i| i.mime_type().to_string());

        Blob {
            id: crate::oid::from_surf(blob.object_id()),
            binary: blob.is_binary(),
            commit: blob.commit().clone().into(),
            content,
            mime_type: mime_type.unwrap_or_else(|| "application/octet-stream".to_string()),
        }
    }
}