about summary refs log tree commit diff stats
path: root/crates/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_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_dlp')
-rw-r--r--crates/yt_dlp/src/lib.rs44
1 files changed, 31 insertions, 13 deletions
diff --git a/crates/yt_dlp/src/lib.rs b/crates/yt_dlp/src/lib.rs
index dc602db..6be5e87 100644
--- a/crates/yt_dlp/src/lib.rs
+++ b/crates/yt_dlp/src/lib.rs
@@ -50,21 +50,36 @@ macro_rules! json_get {
 }
 
 #[macro_export]
+macro_rules! json_try_get {
+    ($value:expr, $name:literal, $into:ident) => {{
+        if let Some(val) = $value.get($name) {
+            if val.is_null() {
+                None
+            } else {
+                Some(json_cast!(@log_key $name, val, $into))
+            }
+        } else {
+            None
+        }
+    }};
+}
+
+#[macro_export]
 macro_rules! json_cast {
     ($value:expr, $into:ident) => {{
-        json_cast!(@log_key "<unknown>", $value, $into)
+        let value_name = stringify!($value);
+        json_cast!(@log_key value_name, $value, $into)
     }};
 
-    (@log_key $name:literal, $value:expr, $into:ident) => {{
+    (@log_key $name:expr, $value:expr, $into:ident) => {{
         match $value.$into() {
             Some(result) => result,
             None => panic!(
                 concat!(
-                    "Expected to be able to cast '",
-                    $name,
-                    "' value ({:#?}) ",
+                    "Expected to be able to cast '{}' value (which is '{:?}') ",
                     stringify!($into)
                 ),
+                $name,
                 $value
             ),
         }
@@ -130,8 +145,9 @@ impl YoutubeDL {
             let info_json = self.extract_info(url, true, true)?;
 
             // Try to work around yt-dlp type weirdness
-            let result_string = if let Some(filename) = info_json.get("filename") {
-                PathBuf::from(json_cast!(filename, as_str))
+            let result_string = if let Some(filename) = json_try_get!(info_json, "filename", as_str)
+            {
+                PathBuf::from(filename)
             } else {
                 PathBuf::from(json_get!(
                     json_cast!(
@@ -195,9 +211,10 @@ impl YoutubeDL {
                     // already resolved. Do nothing
                 } else if let Ok(generator) = generator.downcast::<PyIterator>() {
                     // A python generator object.
-                    let max_backlog = self.options.get("playlistend").map_or(10000, |value| {
-                        usize::try_from(json_cast!(value, as_u64)).expect("Should work")
-                    });
+                    let max_backlog = json_try_get!(self.options, "playlistend", as_u64)
+                        .map_or(10000, |playlistend| {
+                            usize::try_from(playlistend).expect("Should work")
+                        });
 
                     let mut out = vec![];
                     for output in generator {
@@ -211,9 +228,10 @@ impl YoutubeDL {
                     result.set_item(intern!(py, "entries"), out).wrap_exc(py)?;
                 } else {
                     // Probably some sort of paged list (`OnDemand` or otherwise)
-                    let max_backlog = self.options.get("playlistend").map_or(10000, |value| {
-                        usize::try_from(json_cast!(value, as_u64)).expect("Should work")
-                    });
+                    let max_backlog = json_try_get!(self.options, "playlistend", as_u64)
+                        .map_or(10000, |playlistend| {
+                            usize::try_from(playlistend).expect("Should work")
+                        });
 
                     let next = generator.getattr(intern!(py, "getslice")).wrap_exc(py)?;