diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-07-24 16:20:34 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-07-24 16:20:34 +0200 |
commit | a9fddbeebf428eb57c60afab96fbbd38629a636e (patch) | |
tree | 480d9c1ae6f43598bfff7e4a29a378691b0a7508 /crates/yt/src/yt_dlp/mod.rs | |
parent | fix(crates/yt/{commands/playlist,videos/format_video}): Correctly calculate w... (diff) | |
download | yt-a9fddbeebf428eb57c60afab96fbbd38629a636e.zip |
fix(treewide): Use `json_try_get!` instead of `json.get(..).map(|| ..)`
`json.get` will return `Some(Value::Null)` if the json key exists but has been set to `null`. This is obviously not what we want, and as such we also need to check that the value is not null, before calling map. The `json_try_get!` macro does exactly that.
Diffstat (limited to 'crates/yt/src/yt_dlp/mod.rs')
-rw-r--r-- | crates/yt/src/yt_dlp/mod.rs | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/crates/yt/src/yt_dlp/mod.rs b/crates/yt/src/yt_dlp/mod.rs index edf27e8..307ecdc 100644 --- a/crates/yt/src/yt_dlp/mod.rs +++ b/crates/yt/src/yt_dlp/mod.rs @@ -7,7 +7,9 @@ use log::{error, warn}; use serde_json::json; use tokio::{fs, io}; use url::Url; -use yt_dlp::{YoutubeDL, info_json::InfoJson, json_cast, json_get, options::YoutubeDLOptions}; +use yt_dlp::{ + YoutubeDL, info_json::InfoJson, json_cast, json_get, json_try_get, options::YoutubeDLOptions, +}; use crate::{ app::App, @@ -53,20 +55,19 @@ impl Video { .extract_info(&self.url, false, true) .with_context(|| format!("Failed to extract video information: '{}'", self.title))?; - let size = if let Some(val) = result.get("filesize") { - json_cast!(val, as_u64) - } else if let Some(serde_json::Value::Number(num)) = result.get("filesize_approx") { - // NOTE(@bpeetz): yt_dlp sets this value to `Null`, instead of omitting it when it - // can't calculate the approximate filesize. - // Thus, we have to check, that it is actually non-null, before we cast it. <2025-06-15> - json_cast!(num, as_u64) - } else if result.get("duration").is_some() && result.get("tbr").is_some() { + let size = if let Some(filesize) = json_try_get!(result, "filesize", as_u64) { + filesize + } else if let Some(num) = json_try_get!(result, "filesize_approx", as_u64) { + num + } else if let Some(duration) = json_try_get!(result, "duration", as_f64) + && let Some(tbr) = json_try_get!(result, "tbr", as_f64) + { #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] - let duration = json_get!(result, "duration", as_f64).ceil() as u64; + let duration = duration.ceil() as u64; // TODO: yt_dlp gets this from the format #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] - let tbr = json_get!(result, "tbr", as_f64).ceil() as u64; + let tbr = tbr.ceil() as u64; duration * tbr * (1000 / 8) } else { @@ -97,9 +98,7 @@ impl Video { } } - let publish_date = if let Some(date) = &entry.get("upload_date") { - let date = json_cast!(date, as_str); - + let publish_date = if let Some(date) = json_try_get!(entry, "upload_date", as_str) { let year: u32 = date .chars() .take(4) @@ -135,13 +134,16 @@ impl Video { None }; - let thumbnail_url = match (&entry.get("thumbnails"), &entry.get("thumbnail")) { + let thumbnail_url = match ( + &json_try_get!(entry, "thumbnails", as_array), + &json_try_get!(entry, "thumbnail", as_str), + ) { (None, None) => None, - (None, Some(thumbnail)) => Some(Url::from_str(json_cast!(thumbnail, as_str))?), + (None, Some(thumbnail)) => Some(Url::from_str(thumbnail)?), // TODO: The algorithm is not exactly the best <2024-05-28> (Some(thumbnails), None) => { - if let Some(thumbnail) = json_cast!(thumbnails, as_array).first() { + if let Some(thumbnail) = thumbnails.first() { Some(Url::from_str(json_get!( json_cast!(thumbnail, as_object), "url", @@ -151,7 +153,7 @@ impl Video { None } } - (Some(_), Some(thumnail)) => Some(Url::from_str(json_cast!(thumnail, as_str))?), + (Some(_), Some(thumnail)) => Some(Url::from_str(thumnail)?), }; let url = { @@ -171,12 +173,8 @@ impl Video { let subscription_name = if let Some(sub) = sub { Some(sub.name.clone()) - } else if let Some(uploader) = entry.get("uploader").map(|val| json_cast!(val, as_str)) { - if entry - .get("webpage_url_domain") - .map(|val| json_cast!(val, as_str)) - == Some("youtube.com") - { + } else if let Some(uploader) = json_try_get!(entry, "uploader", as_str) { + if json_try_get!(entry, "webpage_url_domain", as_str) == Some("youtube.com") { Some(format!("{uploader} - Videos")) } else { Some(uploader.to_owned()) @@ -186,12 +184,8 @@ impl Video { }; let video = Video { - description: entry - .get("description") - .map(|val| json_cast!(val, as_str).to_owned()), - duration: MaybeDuration::from_maybe_secs_f64( - entry.get("duration").map(|val| json_cast!(val, as_f64)), - ), + description: json_try_get!(entry, "description", as_str).map(ToOwned::to_owned), + duration: MaybeDuration::from_maybe_secs_f64(json_try_get!(entry, "duration", as_f64)), extractor_hash, last_status_change: TimeStamp::from_now(), parent_subscription_name: subscription_name, |