我有一个 JSON 对象,它代表一些松散的配置。我想提供基于某些运行时条件的数据“视图”功能,而不是直接处理数据。
在某些情况下,我仍然需要处理“原始”数据,因此我不想保留相同内容的副本和多次解析。
例如,我有一个这样的婴儿 JSON:
[
{
"type" : "banner",
"text" : "some text",
},
{
"type" : "toolbar",
"text" : "some text",
"color" : "#00FF00",
"texture" : "border",
"shadow" : "#000000"
}
]
我正在将数据解析为与此类似的对象树:
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Data {
values: Vec<Message>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Message {
message_type: MessageType,
text: String,
additional_fields: HashMap<String, Value>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
enum MessageType {
Banner,
Toolbar,
}
// I have some helper functions to find things in the JSON
impl Data {
pub fn get_message_of_type(&self, message_type: MessageType) -> Option<&Message> {
self.values.iter().find(|x| x.message_type == message_type)
}
}
我想要一种方法来返回与MessageType
.
例如,当消息是工具栏时,它还具有其他属性中的“颜色”属性。
我想为它定义一个特征(或其他东西?)Toolbar
并“投射” Message
(或返回一些代理)以帮助处理非常松散的Message
类型。
这是一个人为的例子
// some trait describing toolbar things
trait Toolbar {
fn text() -> String;
fn color() -> String;
fn something_only_toolbar_relevant();
}
// NOT FUNCTIONING! This is what I am trying to figure out
impl Toolbar for Message
where
message_type = "toolbar"
{
fn text() -> String {
self.text
}
fn color() -> String {
let color = self.additional_fields.get("color");
self.additional_fields.get("color").unwrap.as_str()
}
}
// extend the Data class to return "toolbars"
// DOES NOT WORK!!! I am asking how to do this
// SHOULD I CREATE A SHIM OBJECT TO PROXY THIS FUNCTIONALITY?
// IS THERE A LOW COST MECHANISM TO DO THIS WITHOUT CREATING NEW OBJECTS?
impl Data {
fn get_toolbar(&self) -> impl Toolbar {
json.find(|x| x.message_type == MessageType::Toolbar) ????AS???? Toolbar // a view over the object for a toolbar
}
}