2016-09-08 4 views
8

Wie kann ich eine Transformation auf ein Feld vor der Serialisierung anwenden?Wie transformiert man Felder während der Serialisierung mit Serde?

Wie kann ich zum Beispiel sicherstellen, dass die Felder lat und lon in dieser Strukturdefinition auf maximal 6 Dezimalstellen gerundet werden, bevor sie serialisiert werden?

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

manuell implementieren 'Serialize'? – Kroltan

Antwort

7

Sie die serialize_with attribute können a custom serialization function für Ihren Bereich zu schaffen:

#[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, 
} 

(Ich habe auf die nächste ganze Zahl gerundet, das Thema zu vermeiden „, was ist beste Weg, einen Schwimmer abzurunden k Nachkommastellen").

Der andere Halb manuelle Ansatz ist eine separate Struktur mit Auto-abgeleitete Serialisierung zu erstellen und Ihre Serialisierung implementieren mit, dass:

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) 
    } 
} 
Verwandte Themen