有没有办法将Serde地图转换为价值?(Is there a way to convert a Serde Map into a Value?)

编程入门 行业动态 更新时间:2024-10-27 22:25:17
没有办法将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 ?

As per the Serde specification, an Object / Map<String, Value> is a Value:

pub enum Value { Null, Bool(bool), Number(Number), String(String), Array(Vec<Value>), Object(Map<String, Value>), }

Yet when I compile this code:

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 ); }

I get this error:

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
 

Is there a way to downcast a Map into a Value?

最满意答案

Object / Map<String, Value>是一个Value

不它不是。 Value是一种类型。 Map<String, Value>是一种类型。 Value::Object是一个枚举变体 ,它不是一个单独的类型。 在这种情况下, Value::Object包含另一个Map<String, Value>类型的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返回对包含对象(如果存在)的引用,而不是值本身。 您现在需要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), };

an Object / Map<String, Value> is a Value

No, it is not. Value is a type. Map<String, Value> is a type. Value::Object is an enum variant, which is not a separate type. In this case, Value::Object holds another value of type Map<String, Value>. You have to wrap the value in the variant to convert the type:

Err(serde_json::Value::Object(obj))

This will lead you to the problem:

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 a reference to the contained object (if it's present), not the value itself. You will need to match on it for now:

let converted_json = match json { serde_json::Value::Object(obj) => {} _ => {} };

Something like this:

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), };

更多推荐

本文发布于:2023-07-06 07:52:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1047533.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:没有办法   转换为   价值   地图   Map

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!