strawcore/src/image.rs
Kayos 46201c731f Phase 1 — Foundation
Mirror NPE's dependency-free spine in Rust:

* exceptions   — NetworkError + ParsingError + ContentUnavailable
                 + ExtractionError tree, with reqwest/serde_json conversions
* localization — Localization + ContentCountry, default (en, GB)
* downloader/  — Downloader trait, Request builder, Response,
                 reqwest blocking default impl
* page         — continuation-token carrier
* image        — Image + ImageSet + ResolutionLevel
                 (HEIGHT_UNKNOWN/WIDTH_UNKNOWN = -1)
* metainfo     — title/content/url/url_text grab-bag
* service      — StreamingService trait + LinkType + ServiceInfo
* newpipe      — process-global Downloader / Localization /
                 ContentCountry singleton

Foundational invariants nailed down (per SPEC §3):
* HTTP non-2xx returns Ok(Response); only 429 throws NetworkError::Recaptcha
* Response header keys lowercase-normalized
* Request.add_header PARITY with NPE bug (silent overwrite);
  append_header is our clean addition
* default Localization is en-GB
* No cookie jar in the default downloader

Tests: 7 unit + 7 live smoke against httpbin.org (gated on
'online-tests' feature). All green.
2026-05-24 16:32:36 -07:00

72 lines
1.5 KiB
Rust

// Image + ImageSet + ResolutionLevel. Mirrors NPE Image.java.
//
// HEIGHT_UNKNOWN / WIDTH_UNKNOWN are -1 sentinels per SPEC §3 invariant #10
// — kept as i32, not Option<u32>, because several JSON output sites encode
// this directly.
pub const HEIGHT_UNKNOWN: i32 = -1;
pub const WIDTH_UNKNOWN: i32 = -1;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum ResolutionLevel {
Low,
Medium,
High,
Unknown,
}
impl ResolutionLevel {
pub fn from_height(height: i32) -> Self {
if height == HEIGHT_UNKNOWN {
ResolutionLevel::Unknown
} else if height <= 175 {
ResolutionLevel::Low
} else if height <= 720 {
ResolutionLevel::Medium
} else {
ResolutionLevel::High
}
}
}
#[derive(Clone, Debug)]
pub struct Image {
url: String,
height: i32,
width: i32,
estimated_resolution_level: ResolutionLevel,
}
impl Image {
pub fn new(
url: impl Into<String>,
height: i32,
width: i32,
estimated_resolution_level: ResolutionLevel,
) -> Self {
Self {
url: url.into(),
height,
width,
estimated_resolution_level,
}
}
pub fn url(&self) -> &str {
&self.url
}
pub fn height(&self) -> i32 {
self.height
}
pub fn width(&self) -> i32 {
self.width
}
pub fn estimated_resolution_level(&self) -> ResolutionLevel {
self.estimated_resolution_level
}
}
pub type ImageSet = Vec<Image>;