57 lines
1.6 KiB
Rust
57 lines
1.6 KiB
Rust
|
//! Blob utilities which do not require RPC calls.
|
||
|
//!
|
||
|
//! Offers the following functions:
|
||
|
//!
|
||
|
//! - [`get_blob_path()`]
|
||
|
|
||
|
use crate::error::GolgiError;
|
||
|
|
||
|
/// Lookup the filepath for a blob.
|
||
|
///
|
||
|
/// # Example
|
||
|
///
|
||
|
/// ```rust
|
||
|
/// use golgi::blobs;
|
||
|
///
|
||
|
/// fn lookup_blob_path() -> Result<(), GolgiError> {
|
||
|
/// let blob_ref = "&JlJHc9yeG1EpZA9fIPGLzUKDH0FeR39Ai57euhKT1G8=.sha256";
|
||
|
///
|
||
|
/// let blob_path = blobs::get_blob_path(blob_ref)?;
|
||
|
///
|
||
|
/// println!("{}", blob_path);
|
||
|
///
|
||
|
/// // 26/524773dc9e1b5129640f5f20f18bcd42831f415e477f408b9edeba1293d46f
|
||
|
///
|
||
|
/// Ok(())
|
||
|
/// }
|
||
|
/// ```
|
||
|
pub fn get_blob_path(blob_id: &str) -> Result<String, GolgiError> {
|
||
|
let dot_index = blob_id.rfind('.').ok_or_else(|| {
|
||
|
GolgiError::SigilLink(format!(
|
||
|
"Invalid blob ID; no dot index was found: {}",
|
||
|
blob_id
|
||
|
))
|
||
|
})?;
|
||
|
|
||
|
// obtain the base64 portion (substring) of the blob id
|
||
|
let base64_str = &blob_id[1..dot_index];
|
||
|
|
||
|
// decode blob substring from base64 (to bytes)
|
||
|
let blob_bytes = base64::decode_config(base64_str, base64::STANDARD)?;
|
||
|
|
||
|
// represent the blob bytes as hex, removing all unnecessary characters
|
||
|
let blob_hex = format!("{:02x?}", blob_bytes)
|
||
|
.replace('[', "")
|
||
|
.replace(']', "")
|
||
|
.replace(',', "")
|
||
|
.replace(' ', "");
|
||
|
|
||
|
// split the hex representation of the decoded base64
|
||
|
// this is how paths are formatted for the blobstore
|
||
|
// e.g. 26/524773dc9e1b5129640f5f20f18bcd42831f415e477f408b9edeba1293d46f
|
||
|
// full path would be: `/home/user/.ssb-go/blobs/sha256/26/524773dc...`
|
||
|
let blob_path = format!("{}/{}", &blob_hex[..2], &blob_hex[2..]);
|
||
|
|
||
|
Ok(blob_path)
|
||
|
}
|