#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::string::String;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Example<T>(pub T);
impl<T> Example<T> {
#[must_use]
#[inline]
pub const fn new(value: T) -> Self {
Self(value)
}
#[must_use]
#[inline]
pub const fn value(&self) -> &T {
&self.0
}
#[must_use]
#[inline]
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> core::ops::Deref for Example<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> core::ops::DerefMut for Example<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> From<T> for Example<T> {
#[inline]
fn from(value: T) -> Self {
Self(value)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct DeprecatedField {
pub field_name: String,
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub replacement: Option<String>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl DeprecatedField {
#[must_use]
pub fn new(field_name: impl Into<String>) -> Self {
Self {
field_name: field_name.into(),
replacement: None,
}
}
#[must_use]
pub fn with_replacement(mut self, replacement: impl Into<String>) -> Self {
self.replacement = Some(replacement.into());
self
}
#[must_use]
pub fn field_name(&self) -> &str {
&self.field_name
}
#[must_use]
pub fn replacement(&self) -> Option<&str> {
self.replacement.as_deref()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_new_and_deref() {
let ex = Example::new(42u32);
assert_eq!(*ex, 42);
assert_eq!(ex.value(), &42);
}
#[test]
fn example_into_inner() {
let ex = Example::new("hello");
assert_eq!(ex.into_inner(), "hello");
}
#[test]
fn example_from() {
let ex: Example<u32> = 7u32.into();
assert_eq!(*ex, 7);
}
#[test]
fn example_deref_mut() {
let mut ex = Example::new(1u32);
*ex = 2;
assert_eq!(*ex, 2);
}
#[cfg(feature = "serde")]
#[test]
fn example_transparent_serde() {
let ex = Example::new(42u32);
let json = serde_json::to_value(&ex).unwrap();
assert_eq!(json, serde_json::json!(42));
let back: Example<u32> = serde_json::from_value(json).unwrap();
assert_eq!(back, ex);
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[test]
fn deprecated_field_new() {
let d = DeprecatedField::new("old_id");
assert_eq!(d.field_name(), "old_id");
assert!(d.replacement().is_none());
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[test]
fn deprecated_field_with_replacement() {
let d = DeprecatedField::new("old_id").with_replacement("resource_id");
assert_eq!(d.replacement(), Some("resource_id"));
}
#[cfg(all(feature = "serde", any(feature = "std", feature = "alloc")))]
#[test]
fn deprecated_field_serde_omits_none_replacement() {
let d = DeprecatedField::new("legacy");
let json = serde_json::to_value(&d).unwrap();
assert!(json.get("replacement").is_none());
}
#[cfg(all(feature = "serde", any(feature = "std", feature = "alloc")))]
#[test]
fn deprecated_field_serde_round_trip() {
let d = DeprecatedField::new("old").with_replacement("new");
let json = serde_json::to_value(&d).unwrap();
let back: DeprecatedField = serde_json::from_value(json).unwrap();
assert_eq!(back, d);
}
}