mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 05:10:55 +00:00
52 lines
1.5 KiB
Rust
52 lines
1.5 KiB
Rust
|
use std::collections::HashMap;
|
||
|
|
||
|
use anyhow::Result;
|
||
|
use prost_reflect::{DynamicMessage, ReflectMessage, Value};
|
||
|
|
||
|
pub fn proto2dynamic(proto: impl ReflectMessage) -> Result<DynamicMessage> {
|
||
|
Ok(DynamicMessage::decode(
|
||
|
proto.descriptor(),
|
||
|
proto.encode_to_vec().as_slice(),
|
||
|
)?)
|
||
|
}
|
||
|
|
||
|
pub fn proto2kv(proto: impl ReflectMessage) -> Result<HashMap<String, String>> {
|
||
|
let message = proto2dynamic(proto)?;
|
||
|
let mut map = HashMap::new();
|
||
|
|
||
|
fn crawl(prefix: &str, map: &mut HashMap<String, String>, message: &DynamicMessage) {
|
||
|
for (field, value) in message.fields() {
|
||
|
let path = if prefix.is_empty() {
|
||
|
field.name().to_string()
|
||
|
} else {
|
||
|
format!("{}.{}", prefix, field.name())
|
||
|
};
|
||
|
match value {
|
||
|
Value::Message(child) => {
|
||
|
crawl(&path, map, child);
|
||
|
}
|
||
|
|
||
|
Value::EnumNumber(number) => {
|
||
|
if let Some(e) = field.kind().as_enum() {
|
||
|
if let Some(value) = e.get_value(*number) {
|
||
|
map.insert(path, value.name().to_string());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Value::String(value) => {
|
||
|
map.insert(path, value.clone());
|
||
|
}
|
||
|
|
||
|
_ => {
|
||
|
map.insert(path, value.to_string());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
crawl("", &mut map, &message);
|
||
|
|
||
|
Ok(map)
|
||
|
}
|