Skip to content

Commit 9205780

Browse files
authored
chore(unstable): Remove RequiredNullable dead code (#1026)
1 parent 90130a6 commit 9205780

2 files changed

Lines changed: 16 additions & 220 deletions

File tree

src/agent.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6051,6 +6051,22 @@ mod test_serialization {
60516051
assert!(deserialized.current.is_none());
60526052
}
60536053

6054+
#[cfg(feature = "unstable_llm_providers")]
6055+
#[test]
6056+
fn test_provider_info_explicit_null_current_decodes_to_none() {
6057+
// current: null and an omitted current are equivalent on the wire;
6058+
// both must deserialize into None so the disabled state is preserved
6059+
// regardless of which form the peer chose to send.
6060+
let json = json!({
6061+
"id": "main",
6062+
"supported": ["anthropic"],
6063+
"required": true,
6064+
"current": null
6065+
});
6066+
let deserialized: ProviderInfo = serde_json::from_value(json).unwrap();
6067+
assert!(deserialized.current.is_none());
6068+
}
6069+
60546070
#[cfg(feature = "unstable_llm_providers")]
60556071
#[test]
60566072
fn test_list_providers_response_serialization() {

src/serde_util.rs

Lines changed: 0 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! ## Types
44
//!
55
//! - [`MaybeUndefined<T>`] — three-state: undefined (key absent), null, or value.
6-
//! - [`RequiredNullable<T>`] — required-but-nullable: key must be present, value may be null.
76
//! - [`SkipListener`] — [`serde_with::InspectError`] hook used by every
87
//! `VecSkipError` call site in the protocol types.
98
//!
@@ -630,140 +629,6 @@ impl IntoMaybeUndefined<serde_json::Value> for Cow<'_, str> {
630629
}
631630
}
632631

633-
// ---- RequiredNullable<T> ----
634-
635-
/// A value that must be present on the wire but whose value may be `null`.
636-
///
637-
/// Unlike `Option<T>`, which serde treats as an implicitly optional field
638-
/// (defaulting to `None` when absent), `RequiredNullable<T>` requires the key to be
639-
/// present during deserialization. A missing field will produce a
640-
/// deserialization error rather than silently defaulting to `None`.
641-
///
642-
/// On the wire this serializes identically to `Option<T>` — either `null` or
643-
/// the JSON representation of `T`.
644-
///
645-
/// **Note:** The `Deserialize` impl uses `serde_json::Value` internally to
646-
/// enforce the "required" constraint, so this type is JSON-only.
647-
///
648-
/// # Example
649-
///
650-
/// ```rust
651-
/// use agent_client_protocol_schema::RequiredNullable;
652-
/// use serde::{Serialize, Deserialize};
653-
///
654-
/// #[derive(Serialize, Deserialize, Debug, PartialEq)]
655-
/// struct Config {
656-
/// // MUST be present in JSON, but its value can be null
657-
/// value: RequiredNullable<String>,
658-
/// }
659-
///
660-
/// // ✅ Present with a value
661-
/// let c: Config = serde_json::from_str(r#"{"value":"hello"}"#).unwrap();
662-
/// assert_eq!(c.value, RequiredNullable::new("hello".to_string()));
663-
///
664-
/// // ✅ Present as null
665-
/// let c: Config = serde_json::from_str(r#"{"value":null}"#).unwrap();
666-
/// assert_eq!(c.value, RequiredNullable::null());
667-
///
668-
/// // ❌ Missing key — deserialization error
669-
/// assert!(serde_json::from_str::<Config>(r#"{}"#).is_err());
670-
/// ```
671-
#[cfg(feature = "unstable_llm_providers")]
672-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema)]
673-
#[schemars(with = "Option<T>", inline)]
674-
#[non_exhaustive]
675-
pub struct RequiredNullable<T>(pub Option<T>);
676-
677-
#[cfg(feature = "unstable_llm_providers")]
678-
impl<T> Default for RequiredNullable<T> {
679-
fn default() -> Self {
680-
Self(None)
681-
}
682-
}
683-
684-
#[cfg(feature = "unstable_llm_providers")]
685-
impl<T: Serialize> Serialize for RequiredNullable<T> {
686-
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
687-
self.0.serialize(serializer)
688-
}
689-
}
690-
691-
#[cfg(feature = "unstable_llm_providers")]
692-
impl<'de, T: Deserialize<'de>> Deserialize<'de> for RequiredNullable<T> {
693-
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
694-
// Deserialize via serde_json::Value so that `deserialize_any` is called.
695-
// serde's MissingFieldDeserializer errors on `deserialize_any` (good — the
696-
// field is required), whereas `deserialize_option` silently returns None.
697-
let value = serde_json::Value::deserialize(deserializer)?;
698-
if value.is_null() {
699-
Ok(RequiredNullable(None))
700-
} else {
701-
T::deserialize(value)
702-
.map(RequiredNullable::new)
703-
.map_err(serde::de::Error::custom)
704-
}
705-
}
706-
}
707-
708-
#[cfg(feature = "unstable_llm_providers")]
709-
impl<T> RequiredNullable<T> {
710-
/// Creates a `RequiredNullable` containing a value.
711-
#[must_use]
712-
pub fn new(value: T) -> Self {
713-
Self(Some(value))
714-
}
715-
716-
/// Creates a `RequiredNullable` representing `null`.
717-
#[must_use]
718-
pub fn null() -> Self {
719-
Self(None)
720-
}
721-
722-
/// Returns `true` if the value is `null`.
723-
#[must_use]
724-
pub fn is_null(&self) -> bool {
725-
self.0.is_none()
726-
}
727-
728-
/// Returns `true` if the value is present (not null).
729-
#[must_use]
730-
pub fn is_value(&self) -> bool {
731-
self.0.is_some()
732-
}
733-
734-
/// Returns a reference to the contained value, if present.
735-
#[must_use]
736-
pub fn value(&self) -> Option<&T> {
737-
self.0.as_ref()
738-
}
739-
740-
/// Returns a mutable reference to the contained value, if present.
741-
#[must_use]
742-
pub fn value_mut(&mut self) -> Option<&mut T> {
743-
self.0.as_mut()
744-
}
745-
746-
/// Converts into the inner `Option<T>`.
747-
#[must_use]
748-
pub fn into_inner(self) -> Option<T> {
749-
self.0
750-
}
751-
}
752-
753-
#[cfg(feature = "unstable_llm_providers")]
754-
impl<T> From<Option<T>> for RequiredNullable<T> {
755-
fn from(value: Option<T>) -> Self {
756-
Self(value)
757-
}
758-
}
759-
760-
#[cfg(feature = "unstable_llm_providers")]
761-
impl<T> From<RequiredNullable<T>> for Option<T> {
762-
fn from(value: RequiredNullable<T>) -> Self {
763-
value.0
764-
}
765-
}
766-
767632
#[cfg(test)]
768633
mod tests {
769634
use serde::{Deserialize, Serialize};
@@ -957,89 +822,4 @@ mod tests {
957822
value = MaybeUndefined::Value(Err("error"));
958823
assert_eq!(value.transpose(), Err("error"));
959824
}
960-
961-
// ---- RequiredNullable tests ----
962-
963-
#[cfg(feature = "unstable_llm_providers")]
964-
mod nullable_tests {
965-
use super::*;
966-
use serde_json::from_str;
967-
968-
#[derive(Serialize, Deserialize, Debug, PartialEq)]
969-
struct Example {
970-
value: RequiredNullable<String>,
971-
}
972-
973-
#[test]
974-
fn present_with_value() {
975-
let example: Example = from_str(r#"{"value":"hello"}"#).unwrap();
976-
assert_eq!(example.value, RequiredNullable(Some("hello".to_string())));
977-
}
978-
979-
#[test]
980-
fn present_as_null() {
981-
let example: Example = from_str(r#"{"value":null}"#).unwrap();
982-
assert_eq!(example.value, RequiredNullable(None));
983-
}
984-
985-
#[test]
986-
fn missing_key_fails() {
987-
assert!(from_str::<Example>(r"{}").is_err());
988-
}
989-
990-
#[test]
991-
fn serialize_value() {
992-
let example = Example {
993-
value: RequiredNullable(Some("hello".to_string())),
994-
};
995-
assert_eq!(to_value(&example).unwrap(), json!({"value": "hello"}));
996-
}
997-
998-
#[test]
999-
fn serialize_null() {
1000-
let example = Example {
1001-
value: RequiredNullable(None),
1002-
};
1003-
assert_eq!(to_value(&example).unwrap(), json!({"value": null}));
1004-
}
1005-
1006-
#[test]
1007-
fn from_option() {
1008-
let nullable: RequiredNullable<i32> = Some(42).into();
1009-
assert_eq!(nullable, RequiredNullable(Some(42)));
1010-
1011-
let nullable: RequiredNullable<i32> = None.into();
1012-
assert_eq!(nullable, RequiredNullable(None));
1013-
}
1014-
1015-
#[test]
1016-
fn into_option() {
1017-
let option: Option<i32> = RequiredNullable(Some(42)).into();
1018-
assert_eq!(option, Some(42));
1019-
1020-
let option: Option<i32> = RequiredNullable(None).into();
1021-
assert_eq!(option, None);
1022-
}
1023-
1024-
#[test]
1025-
fn methods() {
1026-
let value = RequiredNullable::new(42);
1027-
assert!(value.is_value());
1028-
assert!(!value.is_null());
1029-
assert_eq!(value.value(), Some(&42));
1030-
assert_eq!(value.into_inner(), Some(42));
1031-
1032-
let null: RequiredNullable<i32> = RequiredNullable::null();
1033-
assert!(!null.is_value());
1034-
assert!(null.is_null());
1035-
assert_eq!(null.value(), None);
1036-
assert_eq!(null.into_inner(), None);
1037-
}
1038-
1039-
#[test]
1040-
fn default_is_null() {
1041-
let nullable: RequiredNullable<i32> = RequiredNullable::default();
1042-
assert_eq!(nullable, RequiredNullable(None));
1043-
}
1044-
}
1045825
}

0 commit comments

Comments
 (0)