38 lines
1.4 KiB
Rust
38 lines
1.4 KiB
Rust
//! Live read-only smoke: cargo run --locked --example miruro_probe
|
|
//! Exercises native catalog metadata and stable episode URLs; no playback requests.
|
|
use std::io;
|
|
|
|
use tubular::miruro::{Client, Identity};
|
|
|
|
fn invalid(message: &str) -> io::Error {
|
|
io::Error::new(io::ErrorKind::InvalidData, message)
|
|
}
|
|
|
|
fn main() -> io::Result<()> {
|
|
let client = Client::default();
|
|
let results = client.search("apothecary")?;
|
|
let media = results
|
|
.iter()
|
|
.find(|media| media["id"] == "OERe_a0YS4h-DlsBDOeXwX7HOO6316tw")
|
|
.ok_or_else(|| invalid("Research title no longer appears in search"))?;
|
|
let id = media["id"]
|
|
.as_str()
|
|
.ok_or_else(|| invalid("Missing media ID"))?;
|
|
println!("search: {} records; selected Miruro ID {id}", results.len());
|
|
let detail = client.detail(id, "the-apothecary-diaries-season-3")?;
|
|
let number = detail
|
|
.episodes
|
|
.first()
|
|
.and_then(|episode| episode["episode_number"].as_u64())
|
|
.and_then(|number| u32::try_from(number).ok())
|
|
.ok_or_else(|| invalid("No episode metadata available"))?;
|
|
println!(
|
|
"detail: {} returned episodes; selected episode {number}",
|
|
detail.episodes.len()
|
|
);
|
|
let identity = Identity::new(id.into(), number)?;
|
|
println!("watch URL: {}", identity.watch_url()?);
|
|
println!("PASS: native search -> detail/episodes -> stable watch URL; no playback requests");
|
|
Ok(())
|
|
}
|