有没有办法将 Serde 映射转换为值?
Is there a way to convert a Serde Map into a Value?
根据 Serde 规范,Object
/ Map<String, Value>
是 Value
:
pub enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
然而当我编译这段代码时:
extern crate serde;
#[macro_use]
extern crate serde_json;
#[derive(Debug)]
struct Wrapper {
ok: bool,
data: Option<serde_json::Value>,
}
impl Wrapper {
fn ok() -> Wrapper {
Wrapper {
ok: true,
data: None,
}
}
pub fn data(&mut self, data: serde_json::Value) -> &mut Wrapper {
self.data = Some(data);
self
}
pub fn finalize(self) -> Wrapper {
self
}
}
trait IsValidWrapper {
fn is_valid_wrapper(&self) -> bool;
}
impl IsValidWrapper for serde_json::Map<std::string::String, serde_json::Value> {
fn is_valid_wrapper(&self) -> bool {
self["ok"].as_bool().unwrap_or(false)
}
}
fn main() {
let json = json!({
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
});
let converted_json: Wrapper = json
.as_object()
.map_or_else(
|| Err(json),
|obj| {
if obj.is_valid_wrapper() {
Ok(Wrapper::ok().data(obj["data"].clone()).finalize())
} else {
Err(*obj as serde_json::Value)
}
},
)
.unwrap_or_else(|data| Wrapper::ok().data(data.clone()).finalize());
println!(
"org json = {:?} => converted json = {:?}",
json, converted_json
);
}
我收到这个错误:
error[E0605]: non-primitive cast: `serde_json::Map<std::string::String, serde_json::Value>` as `serde_json::Value`
--> src/main.rs:60:25
|
60 | Err(*obj as serde_json::Value)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
有没有办法将 Map
向下转换为 Value
?
an Object
/ Map<String, Value>
is a Value
不,不是。 Value
是一种类型。 Map<String, Value>
是一种类型。 Value::Object
是一个 枚举变体 ,它不是一个单独的类型。在这种情况下,Value::Object
包含另一个类型 Map<String, Value>
的值。您必须将值包装在变体中才能转换类型:
Err(serde_json::Value::Object(obj))
这将导致您遇到问题:
error[E0308]: mismatched types
--> src/main.rs:57:55
|
57 | Err(serde_json::Value::Object(obj))
| ^^^ expected struct `serde_json::Map`, found reference
|
= note: expected type `serde_json::Map<std::string::String, serde_json::Value>`
found type `&serde_json::Map<std::string::String, serde_json::Value>`
as_object
returns 对包含对象(如果存在)的引用,而不是值本身。您现在需要 match
:
let converted_json = match json {
serde_json::Value::Object(obj) => {}
_ => {}
};
像这样:
let converted_json = match json {
serde_json::Value::Object(obj) => {
if obj.is_valid_wrapper() {
let mut w = Wrapper::ok();
w.data(obj["data"].clone());
Ok(w.finalize())
} else {
Err(serde_json::Value::Object(obj))
}
}
other => Err(other),
};
根据 Serde 规范,Object
/ Map<String, Value>
是 Value
:
pub enum Value {
Null,
Bool(bool),
Number(Number),
String(String),
Array(Vec<Value>),
Object(Map<String, Value>),
}
然而当我编译这段代码时:
extern crate serde;
#[macro_use]
extern crate serde_json;
#[derive(Debug)]
struct Wrapper {
ok: bool,
data: Option<serde_json::Value>,
}
impl Wrapper {
fn ok() -> Wrapper {
Wrapper {
ok: true,
data: None,
}
}
pub fn data(&mut self, data: serde_json::Value) -> &mut Wrapper {
self.data = Some(data);
self
}
pub fn finalize(self) -> Wrapper {
self
}
}
trait IsValidWrapper {
fn is_valid_wrapper(&self) -> bool;
}
impl IsValidWrapper for serde_json::Map<std::string::String, serde_json::Value> {
fn is_valid_wrapper(&self) -> bool {
self["ok"].as_bool().unwrap_or(false)
}
}
fn main() {
let json = json!({
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
});
let converted_json: Wrapper = json
.as_object()
.map_or_else(
|| Err(json),
|obj| {
if obj.is_valid_wrapper() {
Ok(Wrapper::ok().data(obj["data"].clone()).finalize())
} else {
Err(*obj as serde_json::Value)
}
},
)
.unwrap_or_else(|data| Wrapper::ok().data(data.clone()).finalize());
println!(
"org json = {:?} => converted json = {:?}",
json, converted_json
);
}
我收到这个错误:
error[E0605]: non-primitive cast: `serde_json::Map<std::string::String, serde_json::Value>` as `serde_json::Value`
--> src/main.rs:60:25
|
60 | Err(*obj as serde_json::Value)
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
有没有办法将 Map
向下转换为 Value
?
an
Object
/Map<String, Value>
is aValue
不,不是。 Value
是一种类型。 Map<String, Value>
是一种类型。 Value::Object
是一个 枚举变体 ,它不是一个单独的类型。在这种情况下,Value::Object
包含另一个类型 Map<String, Value>
的值。您必须将值包装在变体中才能转换类型:
Err(serde_json::Value::Object(obj))
这将导致您遇到问题:
error[E0308]: mismatched types
--> src/main.rs:57:55
|
57 | Err(serde_json::Value::Object(obj))
| ^^^ expected struct `serde_json::Map`, found reference
|
= note: expected type `serde_json::Map<std::string::String, serde_json::Value>`
found type `&serde_json::Map<std::string::String, serde_json::Value>`
as_object
returns 对包含对象(如果存在)的引用,而不是值本身。您现在需要 match
:
let converted_json = match json {
serde_json::Value::Object(obj) => {}
_ => {}
};
像这样:
let converted_json = match json {
serde_json::Value::Object(obj) => {
if obj.is_valid_wrapper() {
let mut w = Wrapper::ok();
w.data(obj["data"].clone());
Ok(w.finalize())
} else {
Err(serde_json::Value::Object(obj))
}
}
other => Err(other),
};