From d86e9eced02ce657820647fe18c5f312aabaa2d6 Mon Sep 17 00:00:00 2001
From: Kyle Barron <kyle@developmentseed.org>
Date: Fri, 26 Apr 2024 11:22:48 -0400
Subject: [PATCH] Allow `None` in rehydration

---
 src/pypgstac/src/lib.rs                      |  6 +++++-
 src/pypgstac/tests/hydration/test_hydrate.py | 11 ++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/pypgstac/src/lib.rs b/src/pypgstac/src/lib.rs
index 87a008c2..1ee96390 100644
--- a/src/pypgstac/src/lib.rs
+++ b/src/pypgstac/src/lib.rs
@@ -38,12 +38,16 @@ fn hydrate_any<'a>(base: &PyAny, item: &'a PyAny) -> PyResult<&'a PyAny> {
     if let Ok(item) = item.downcast::<PyDict>() {
         if let Ok(base) = base.downcast::<PyDict>() {
             hydrate_dict(base, item).map(|item| item.into())
+        } else if base.is_none() {
+            Ok(item)
         } else {
             Err(anyhow!("type mismatch").into())
         }
     } else if let Ok(item) = item.downcast::<PyList>() {
         if let Ok(base) = base.downcast::<PyList>() {
             hydrate_list(base, item).map(|item| item.into())
+        } else if base.is_none() {
+            Ok(item)
         } else {
             Err(anyhow!("type mismatch").into())
         }
@@ -73,7 +77,7 @@ fn hydrate_dict<'a>(base: &PyDict, item: &'a PyDict) -> PyResult<&'a PyDict> {
                 .map(|s| s == MAGIC_MARKER)
                 .unwrap_or(false)
             {
-                item.del_item(&key)?;
+                item.del_item(key)?;
             } else {
                 item.set_item(key, hydrate(base_value, item_value)?)?;
             }
diff --git a/src/pypgstac/tests/hydration/test_hydrate.py b/src/pypgstac/tests/hydration/test_hydrate.py
index ec6b0669..d6928353 100644
--- a/src/pypgstac/tests/hydration/test_hydrate.py
+++ b/src/pypgstac/tests/hydration/test_hydrate.py
@@ -1,4 +1,5 @@
 """Test Hydration."""
+
 import json
 from copy import deepcopy
 from pathlib import Path
@@ -35,7 +36,9 @@
 
 class TestHydrate:
     def hydrate(
-        self, base_item: Dict[str, Any], item: Dict[str, Any],
+        self,
+        base_item: Dict[str, Any],
+        item: Dict[str, Any],
     ) -> Dict[str, Any]:
         hpy = hydration.hydrate_py(deepcopy(base_item), deepcopy(item))
         hrs = hydration.hydrate(deepcopy(base_item), deepcopy(item))
@@ -234,3 +237,9 @@ def test_top_level_base_keys_marked(self) -> None:
         hydrated = self.hydrate(base_item, dehydrated)
 
         assert hydrated == {"included": "value", "unique": "value"}
+
+    def test_base_none(self) -> None:
+        base_item = {"value": None}
+        dehydrated = {"value": {"a": "b"}}
+        hydrated = self.hydrate(base_item, dehydrated)
+        assert hydrated == {"value": {"a": "b"}}