Files
meta-feeder-opensubtitles/feeder-plugin/opensubtitles-feeder/src/locator.rs
T
Worph 2f3ca57322
Publish image / publish (push) Failing after 14s
improve compute API
2026-09-13 14:31:17 +02:00

81 lines
3.1 KiB
Rust

//! The `provider-file` locator (`0x100A`) — `docs/cid-formats.md` §8.
//!
//! One codec for every provider whose bytes are fetched the same way; the
//! provider lives inside the digest:
//!
//! ```text
//! version : 1
//! codec : 0x100A (varint 8a 20)
//! multihash : 0x00 (identity — payload verbatim)
//! digest : varint(len(source)) ‖ source ‖ id (both UTF-8, ≤ 64 bytes)
//! ```
//!
//! The encoder/decoder live in `meta-feeder-sdk` (`hash::compute_provider_file_cid`
//! / `decode_provider_file_cid`, with the §8.2 golden vector); this module only
//! binds them to OpenSubtitles' `file:<file_id>` id form.
use crate::consts::UPSTREAM_ID;
pub use meta_feeder_sdk::hash::{
compute_provider_file_cid as provider_file_cid, decode_provider_file_cid, PROVIDER_FILE_CODEC,
};
/// The locator for one OpenSubtitles **file** (`/download` takes a `file_id`;
/// one subtitle listing can hold several files, one per CD).
pub fn file_cid(file_id: u64) -> Option<String> {
provider_file_cid(UPSTREAM_ID, &format!("file:{file_id}"))
}
/// The OpenSubtitles `file_id` a `/compute` record id names, if it is ours.
///
/// Accepts both shapes a caller holds: the `provider-file` cid (what the
/// gateway's redeem route sends) and this feeder's own record id
/// `opensubtitles:file:<id>`. A cid for another source is `None` — not ours.
pub fn file_id_of(record_id: &str) -> Option<u64> {
if let Some(id) = record_id.strip_prefix(&format!("{UPSTREAM_ID}:file:")) {
return id.parse().ok();
}
let (source, id) = decode_provider_file_cid(record_id)?;
if source != UPSTREAM_ID {
return None;
}
id.strip_prefix("file:")?.parse().ok()
}
#[cfg(test)]
mod tests {
use super::*;
/// `docs/cid-formats.md` §8.2 worked example — still minted identically now
/// that the encoder lives in the SDK.
#[test]
fn file_cid_matches_the_documented_vector() {
assert_eq!(
file_cid(7061834).as_deref(),
Some("bagfcaaa2bvxxazloon2we5djorwgk43gnfwgkorxga3dcobtgq")
);
}
#[test]
fn decode_round_trips_and_refuses_other_codecs() {
let cid = file_cid(12658754).unwrap();
assert_eq!(
decode_provider_file_cid(&cid),
Some(("opensubtitles".to_string(), "file:12658754".to_string()))
);
// Identical framing, different codec: a card must not decode as a file.
assert_eq!(decode_provider_file_cid("bagdsaaanar2g2zdcor3duojvgq3ts"), None);
assert_eq!(decode_provider_file_cid("not-a-cid"), None);
}
#[test]
fn file_id_of_accepts_both_record_id_shapes() {
assert_eq!(file_id_of(&file_cid(7061834).unwrap()), Some(7061834));
assert_eq!(file_id_of("opensubtitles:file:7061834"), Some(7061834));
// Another provider's file, a card, and garbage are not ours.
assert_eq!(file_id_of(&provider_file_cid("other", "file:1").unwrap()), None);
assert_eq!(file_id_of("bagdsaaanar2g2zdcor3duojvgq3ts"), None);
assert_eq!(file_id_of("opensubtitles:file:abc"), None);
}
}