serde_devo/lib.rs
1use std::fmt;
2
3extern crate serde_devo_derive;
4use serde::Deserialize;
5pub use serde_devo_derive::Devolve;
6
7#[derive(Debug, Clone, Deserialize)]
8pub enum Error {
9 UnknownVariant {
10 #[serde(borrow)]
11 ty: &'static str,
12 #[serde(borrow)]
13 path: Vec<&'static str>,
14 },
15}
16impl std::error::Error for Error {}
17impl fmt::Display for Error {
18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19 match self {
20 Self::UnknownVariant { ty, path } => {
21 write!(
22 f,
23 "evolution failed: {ty}.{}",
24 path.iter().fold("[unknown_variant]".to_string(), |a, b| {
25 format!("{b}.{a}")
26 })
27 )
28 }
29 }
30 }
31}
32
33impl Error {
34 pub fn extend(self, ty: &'static str, ext: &'static str) -> Self {
35 match self {
36 Self::UnknownVariant { mut path, .. } => {
37 path.push(ext);
38 Self::UnknownVariant { ty, path }
39 }
40 }
41 }
42}
43
44/// A **data structure** which represents the complete, or latest known form of another
45/// devolved **data structure**, and which may be converted into this "devolved" form.
46///
47/// Additionally, serde-devo provides a procedural macro called [`serde_devo_derive`]
48/// to automatically implement `Devolvable` for structs and enums in your program.
49///
50/// In rare cases it may be necessary to implement `Devolvable` manually for some
51/// type in your program.
52#[cfg(feature = "json")]
53pub trait Devolve<T = serde_json::Value> {
54 type Devolved: Evolve<T, Evolved = Self>;
55 fn into_devolved(self) -> Self::Devolved;
56}
57
58/// A **data structure** which represents the complete, or latest known form of another
59/// devolved **data structure**, and which may be converted into this "devolved" form.
60///
61/// Additionally, serde-devo provides a procedural macro called [`serde_devo_derive`]
62/// to automatically implement `Devolvable` for structs and enums in your program.
63///
64/// In rare cases it may be necessary to implement `Devolvable` manually for some
65/// type in your program.
66#[cfg(not(feature = "json"))]
67pub trait Devolve<T> {
68 type Devolved: Evolve<T, Evolved = Self>;
69 fn into_devolved(self) -> Self::Devolved;
70}
71
72/// A **data structure** which represents the potentially incomplete form of another
73/// evolving **data structure**, and which may be converted into this "evolved" form
74/// with possibility for error.
75///
76/// Additionally, serde-devo provides a procedural macro called [`serde_devo_derive`]
77/// to automatically generate `Evolvable` types for structs and enums in your program.
78///
79/// In rare cases it may be necessary to implement `Evolvable` manually for some
80/// type in your program.
81pub trait Evolve<T>: Sized {
82 type Evolved: Devolve<T, Devolved = Self>;
83 fn try_into_evolved(self) -> Result<Self::Evolved, Error>;
84}