2016-09-08 23 views
8

Jak zastosować transformację do pola przed serializacją?Jak przekształcać pola podczas serializacji za pomocą Serde?

Na przykład, w jaki sposób można się upewnić, że pola lat i lon w tej definicji struktury są zaokrąglone do co najwyżej 6 miejsc dziesiętnych przed serializacją?

#[derive(Debug, Serialize)] 
struct NodeLocation { 
    #[serde(rename = "nodeId")] 
    id: u32, 
    lat: f32, 
    lon: f32, 
} 
+1

Ręczne wdrożenie 'Serialize'? – Kroltan

Odpowiedz

7

Można użyć serialize_with attribute dostarczenie a custom serialization function dla swojej dziedzinie:

#[macro_use] 
extern crate serde_derive; 

extern crate serde; 
use serde::Serializer; 

fn round_serialize<S>(x: &f32, s: S) -> Result<S::Ok, S::Error> 
where 
    S: Serializer, 
{ 
    s.serialize_f32(x.round()) 
} 

#[derive(Debug, Serialize)] 
pub struct NodeLocation { 
    #[serde(rename = "nodeId")] 
    id: u32, 
    #[serde(serialize_with = "round_serialize")] 
    lat: f32, 
    #[serde(serialize_with = "round_serialize")] 
    lon: f32, 
} 

(mam zaokrągleniu do najbliższej liczby całkowitej, aby uniknąć tematu „co jest najlepszym sposobem zaokrąglić pływaka do k miejsca dziesiętne").

Drugi semi-manual rozwiązaniem jest utworzenie osobnego struct z auto-pochodzić serializacji i wdrożyć za pomocą serializacji że:

impl Serialize for NodeLocation { 
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> 
    where 
     S: Serializer, 
    { 
     // Implement your preprocessing in `from`. 
     RoundedNodeLocation::from(loc).serialize(s) 
    } 
}