Open lizelive opened 2 years ago
fn proto_value_to_serde_value(value: prost_types::Value) -> serde_value::Value { match value.kind { Some(prost_types::value::Kind::NullValue(_)) => serde_value::Value::Unit, Some(prost_types::value::Kind::NumberValue(x)) => serde_value::Value::F64(x), Some(prost_types::value::Kind::StringValue(x)) => serde_value::Value::String(x), Some(prost_types::value::Kind::BoolValue(x)) => serde_value::Value::Bool(x), Some(prost_types::value::Kind::StructValue(x)) => serde_value::Value::Map( x.fields .into_iter() .map(|(k, v)| (serde_value::Value::String(k), proto_value_to_serde_value(v))) .collect(), ), Some(prost_types::value::Kind::ListValue(x)) => serde_value::Value::Seq( x.values .into_iter() .map(proto_value_to_serde_value) .collect(), ), None => todo!("not sure if this happens"), //_ => todo!("did not see that coming"), } } #[derive(thiserror::Error, Debug)] pub enum ValueCastError { #[error("invalid key")] InvalidKey, #[error("no matching type")] NoMatchingType, } fn serde_value_to_proto_value(value: serde_value::Value) -> prost_types::Value { match value { serde_value::Value::Bool(x) => prost_types::Value { kind: Some(prost_types::value::Kind::BoolValue(x)), }, serde_value::Value::U8(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::U16(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::U32(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::U64(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x as f64)), }, serde_value::Value::I64(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x as f64)), }, serde_value::Value::I8(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::I16(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::I32(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::F32(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::F64(x) => prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }, serde_value::Value::Char(x) => prost_types::Value { kind: Some(prost_types::value::Kind::StringValue(x.into())), }, serde_value::Value::String(x) => prost_types::Value { kind: Some(prost_types::value::Kind::StringValue(x.into())), }, serde_value::Value::Unit => prost_types::Value { kind: Some(prost_types::value::Kind::NullValue(0)), }, serde_value::Value::Option(x) => { x.map(|x| serde_value_to_proto_value(*x)) .unwrap_or(prost_types::Value { kind: Some(prost_types::value::Kind::NullValue(0)), }) } serde_value::Value::Newtype(x) => serde_value_to_proto_value(*x), serde_value::Value::Seq(x) => { let values = x.into_iter().map(serde_value_to_proto_value).collect(); prost_types::Value { kind: Some(prost_types::value::Kind::ListValue( prost_types::ListValue { values }, )), } } serde_value::Value::Map(x) => prost_types::Value { kind: Some(prost_types::value::Kind::StructValue(prost_types::Struct { fields: x .into_iter() .map(|(k, v)| match (k, serde_value_to_proto_value(v)) { (serde_value::Value::String(k), v) => (k, v), _ => panic!("InvalidKey"), }) .collect(), })), }, serde_value::Value::Bytes(x) => prost_types::Value { kind: Some(prost_types::value::Kind::ListValue( prost_types::ListValue { values: x .into_iter() .map(|x| prost_types::Value { kind: Some(prost_types::value::Kind::NumberValue(x.into())), }) .collect(), }, )), }, } } const NANOS_PER_SECOND: i64 = 1000000; fn chrono_to_prost_timestamp(timestamp: chrono::DateTime<chrono::Utc>) -> prost_types::Timestamp { let nanos = timestamp.timestamp_nanos(); let seconds = nanos / NANOS_PER_SECOND; let nanos = (nanos % NANOS_PER_SECOND) as i32; prost_types::Timestamp { nanos, seconds } } fn prost_timestamp_to_chrono(timestamp: prost_types::Timestamp) -> chrono::DateTime<chrono::Utc> { let nanos = timestamp.seconds * NANOS_PER_SECOND + timestamp.nanos as i64; chrono::Utc.timestamp_nanos(nanos) } serde_with::serde_conv!( ProtoDatetimeAsChrono, Option<prost_types::Timestamp>, |value: &Option<prost_types::Timestamp>| { value.clone().map(prost_timestamp_to_chrono) }, |value: Option<chrono::DateTime<chrono::Utc>>| -> Result<_, std::convert::Infallible> { Ok(value.map(chrono_to_prost_timestamp)) } ); serde_with::serde_conv!( ProtoValueAsSerdeValue, Option<prost_types::Value>, |value: &Option<prost_types::Value>| { value.clone().map(proto_value_to_serde_value) }, |value: Option<serde_value::Value>| -> Result<_, std::convert::Infallible> { Ok(value.map(serde_value_to_proto_value)) } );
Could you expand on what you're looking for?
There's 1,000,000,000 nanoseconds per second, not 1,000,000.