about summary refs log tree commit diff stats
path: root/crates/yt/src/yt_dlp
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-24 16:20:34 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-24 16:20:34 +0200
commita9fddbeebf428eb57c60afab96fbbd38629a636e (patch)
tree480d9c1ae6f43598bfff7e4a29a378691b0a7508 /crates/yt/src/yt_dlp
parentfix(crates/yt/{commands/playlist,videos/format_video}): Correctly calculate w... (diff)
downloadyt-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')
-rw-r--r--crates/yt/src/yt_dlp/mod.rs54
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,