|
| 1 | +use std::sync::Arc; |
| 2 | + |
| 3 | +use ordered_float::OrderedFloat; |
| 4 | + |
1 | 5 | use super::{FuncValueType, MaybeRV, RowVariable, SumType, TypeBase, TypeBound, TypeEnum}; |
2 | 6 |
|
3 | 7 | use super::custom::CustomType; |
4 | 8 |
|
5 | 9 | use crate::extension::SignatureError; |
6 | 10 | use crate::extension::prelude::{qb_t, usize_t}; |
7 | 11 | use crate::ops::AliasDecl; |
| 12 | +use crate::types::type_param::{TypeArgVariable, UpperBound}; |
| 13 | +use crate::types::{Term, Type}; |
8 | 14 |
|
9 | 15 | #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] |
10 | 16 | #[serde(tag = "t")] |
@@ -60,3 +66,133 @@ impl<RV: MaybeRV> TryFrom<SerSimpleType> for TypeBase<RV> { |
60 | 66 | }) |
61 | 67 | } |
62 | 68 | } |
| 69 | + |
| 70 | +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] |
| 71 | +#[non_exhaustive] |
| 72 | +#[serde(tag = "tp")] |
| 73 | +pub(super) enum TypeParamSer { |
| 74 | + Type { b: TypeBound }, |
| 75 | + BoundedNat { bound: UpperBound }, |
| 76 | + String, |
| 77 | + Bytes, |
| 78 | + Float, |
| 79 | + StaticType, |
| 80 | + List { param: Box<Term> }, |
| 81 | + Tuple { params: Vec<Term> }, |
| 82 | +} |
| 83 | + |
| 84 | +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] |
| 85 | +#[non_exhaustive] |
| 86 | +#[serde(tag = "tya")] |
| 87 | +pub(super) enum TypeArgSer { |
| 88 | + Type { |
| 89 | + ty: Type, |
| 90 | + }, |
| 91 | + BoundedNat { |
| 92 | + n: u64, |
| 93 | + }, |
| 94 | + String { |
| 95 | + arg: String, |
| 96 | + }, |
| 97 | + Bytes { |
| 98 | + #[serde(with = "base64")] |
| 99 | + value: Arc<[u8]>, |
| 100 | + }, |
| 101 | + Float { |
| 102 | + value: OrderedFloat<f64>, |
| 103 | + }, |
| 104 | + List { |
| 105 | + elems: Vec<Term>, |
| 106 | + }, |
| 107 | + Tuple { |
| 108 | + elems: Vec<Term>, |
| 109 | + }, |
| 110 | + Variable { |
| 111 | + #[serde(flatten)] |
| 112 | + v: TypeArgVariable, |
| 113 | + }, |
| 114 | +} |
| 115 | + |
| 116 | +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] |
| 117 | +#[serde(untagged)] |
| 118 | +pub(super) enum TermSer { |
| 119 | + TypeArg(TypeArgSer), |
| 120 | + TypeParam(TypeParamSer), |
| 121 | +} |
| 122 | + |
| 123 | +impl From<Term> for TermSer { |
| 124 | + fn from(value: Term) -> Self { |
| 125 | + match value { |
| 126 | + Term::RuntimeType { b } => TermSer::TypeParam(TypeParamSer::Type { b }), |
| 127 | + Term::StaticType => TermSer::TypeParam(TypeParamSer::StaticType), |
| 128 | + Term::BoundedNatType { bound } => { |
| 129 | + TermSer::TypeParam(TypeParamSer::BoundedNat { bound }) |
| 130 | + } |
| 131 | + Term::StringType => TermSer::TypeParam(TypeParamSer::String), |
| 132 | + Term::BytesType => TermSer::TypeParam(TypeParamSer::Bytes), |
| 133 | + Term::FloatType => TermSer::TypeParam(TypeParamSer::Float), |
| 134 | + Term::ListType { param } => TermSer::TypeParam(TypeParamSer::List { |
| 135 | + param: Box::new(*param), |
| 136 | + }), |
| 137 | + Term::TupleType { params } => TermSer::TypeParam(TypeParamSer::Tuple { params }), |
| 138 | + Term::Type { ty } => TermSer::TypeArg(TypeArgSer::Type { ty }), |
| 139 | + Term::BoundedNat { n } => TermSer::TypeArg(TypeArgSer::BoundedNat { n }), |
| 140 | + Term::String { arg } => TermSer::TypeArg(TypeArgSer::String { arg }), |
| 141 | + Term::Bytes { value } => TermSer::TypeArg(TypeArgSer::Bytes { value }), |
| 142 | + Term::Float { value } => TermSer::TypeArg(TypeArgSer::Float { value }), |
| 143 | + Term::List { elems } => TermSer::TypeArg(TypeArgSer::List { elems }), |
| 144 | + Term::Tuple { elems } => TermSer::TypeArg(TypeArgSer::Tuple { elems }), |
| 145 | + Term::Variable { v } => TermSer::TypeArg(TypeArgSer::Variable { v }), |
| 146 | + } |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +impl From<TermSer> for Term { |
| 151 | + fn from(value: TermSer) -> Self { |
| 152 | + match value { |
| 153 | + TermSer::TypeParam(param) => match param { |
| 154 | + TypeParamSer::Type { b } => Term::RuntimeType { b }, |
| 155 | + TypeParamSer::StaticType => Term::StaticType, |
| 156 | + TypeParamSer::BoundedNat { bound } => Term::BoundedNatType { bound }, |
| 157 | + TypeParamSer::String => Term::StringType, |
| 158 | + TypeParamSer::Bytes => Term::BytesType, |
| 159 | + TypeParamSer::Float => Term::FloatType, |
| 160 | + TypeParamSer::List { param } => Term::ListType { param }, |
| 161 | + TypeParamSer::Tuple { params } => Term::TupleType { params }, |
| 162 | + }, |
| 163 | + TermSer::TypeArg(arg) => match arg { |
| 164 | + TypeArgSer::Type { ty } => Term::Type { ty }, |
| 165 | + TypeArgSer::BoundedNat { n } => Term::BoundedNat { n }, |
| 166 | + TypeArgSer::String { arg } => Term::String { arg }, |
| 167 | + TypeArgSer::Bytes { value } => Term::Bytes { value }, |
| 168 | + TypeArgSer::Float { value } => Term::Float { value }, |
| 169 | + TypeArgSer::List { elems } => Term::List { elems }, |
| 170 | + TypeArgSer::Tuple { elems } => Term::Tuple { elems }, |
| 171 | + TypeArgSer::Variable { v } => Term::Variable { v }, |
| 172 | + }, |
| 173 | + } |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +/// Helper for to serialize and deserialize the byte string in [`TypeArg::Bytes`] via base64. |
| 178 | +mod base64 { |
| 179 | + use std::sync::Arc; |
| 180 | + |
| 181 | + use base64::Engine as _; |
| 182 | + use base64::prelude::BASE64_STANDARD; |
| 183 | + use serde::{Deserialize, Serialize}; |
| 184 | + use serde::{Deserializer, Serializer}; |
| 185 | + |
| 186 | + pub fn serialize<S: Serializer>(v: &Arc<[u8]>, s: S) -> Result<S::Ok, S::Error> { |
| 187 | + let base64 = BASE64_STANDARD.encode(v); |
| 188 | + base64.serialize(s) |
| 189 | + } |
| 190 | + |
| 191 | + pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Arc<[u8]>, D::Error> { |
| 192 | + let base64 = String::deserialize(d)?; |
| 193 | + BASE64_STANDARD |
| 194 | + .decode(base64.as_bytes()) |
| 195 | + .map(|v| v.into()) |
| 196 | + .map_err(serde::de::Error::custom) |
| 197 | + } |
| 198 | +} |
0 commit comments