// Page — continuation token carrier. Mirrors NPE Page.java. // // Used everywhere "the next page" is paginated through an opaque token // (search results, channel videos, playlist videos, comments). The fields // are deliberately a grab-bag — NPE callers stuff whatever they need to // resume. use std::collections::BTreeMap; #[derive(Clone, Debug, Default)] pub struct Page { url: Option, id: Option, ids: Vec, body: Option>, cookies: BTreeMap, } impl Page { pub fn new() -> Self { Self::default() } pub fn with_url(url: impl Into) -> Self { Self { url: Some(url.into()), ..Self::default() } } pub fn url(&self) -> Option<&str> { self.url.as_deref() } pub fn set_url(&mut self, url: Option) -> &mut Self { self.url = url; self } pub fn id(&self) -> Option<&str> { self.id.as_deref() } pub fn set_id(&mut self, id: Option) -> &mut Self { self.id = id; self } pub fn ids(&self) -> &[String] { &self.ids } pub fn set_ids(&mut self, ids: Vec) -> &mut Self { self.ids = ids; self } pub fn body(&self) -> Option<&[u8]> { self.body.as_deref() } pub fn set_body(&mut self, body: Option>) -> &mut Self { self.body = body; self } pub fn cookies(&self) -> &BTreeMap { &self.cookies } pub fn set_cookies(&mut self, cookies: BTreeMap) -> &mut Self { self.cookies = cookies; self } pub fn is_valid(&self) -> bool { self.url.as_deref().map(|s| !s.is_empty()).unwrap_or(false) || self.id.as_deref().map(|s| !s.is_empty()).unwrap_or(false) || !self.ids.is_empty() || self.body.as_ref().map(|b| !b.is_empty()).unwrap_or(false) } }