Skip to content

json::PrettyEncoder won't encode some values #14891

Closed
@vojtechkral

Description

@vojtechkral

Hi,
I ran into a problem with json::PrettyEncoder, it won't encode values with emit_struct_field() whereas the regular json::Encoder works just fine using exactly the same code.

This is the code to reproduce:

extern crate serialize;

use std::io::stdio;
use serialize::{json, Decodable, Encodable};

mod Geo {
    use std::fmt;
    use serialize::{Decodable, Decoder, Encodable, Encoder};

    pub struct Location {
        name: String,
        lat: f32,
        lon: f32
    }

    impl Location {
        pub fn new(name: &String, lat: f32, lon: f32) -> Location {
            let mut loc = Location { name: name.clone(), lat: 0.0, lon: 0.0 };
            loc.set_coords(lat, lon);
            loc
        }

        pub fn set_coords(&mut self, lat: f32, lon: f32) {
            self.lat = match lat {
                -90.0..90.0 => lat, l if l > 90.0 => 90.0, _ => -90.0
            };
            self.lon = match lon {
                -180.0..180.0 => lon, l if l > 180.0 => 180.0, _ => -180.0
            };
        }
    }

    impl fmt::Show for Location {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let lat_h = if self.lat >= 0.0 {'N'} else {'S'};
            let lon_h = if self.lat >= 0.0 {'E'} else {'W'};
            write!(f, "{}: {}°{}, {}°{}", self.name,
                   self.lat, lat_h, self.lon, lon_h)
        }
    }

    impl<E, D: Decoder<E>> Decodable<D, E> for Location {
        fn decode(d: &mut D) -> Result<Location, E> {
            d.read_struct("", 0, |d| {
                let name: String = try!(d.read_struct_field("name", 0, |d| Decodable::decode(d)));
                let lat: f32 = try!(d.read_struct_field("lat", 0, |d| Decodable::decode(d)));
                let lon: f32 = try!(d.read_struct_field("lon", 0, |d| Decodable::decode(d)));
                Ok(Location::new(&name, lat, lon))
            })
        }
    }

    impl<E, S: Encoder<E>> Encodable<S, E> for Location {
        fn encode(&self, s: &mut S) -> Result<(), E> {
            s.emit_struct("a", 0, |s| {
                try!(s.emit_struct_field("name", 0, |s| self.name.encode(s)));
                try!(s.emit_struct_field("lat",  1, |s| self.lat.encode(s)));
                try!(s.emit_struct_field("lon",  2, |s| self.lon.encode(s)));
                Ok(())
            })
        }
    }
}

static json: &'static str = "[
    {\"name\": \"Prague\", \"lat\": 50.082542, \"lon\": 14.425992},
    {\"name\": \"London\", \"lat\": 51.507222, \"lon\": -0.1275},
    {\"name\": \"Far far away\", \"lat\": 0.0, \"lon\": 9001.0}
]";


fn main() {
    let json_object = json::from_str(json);
    let mut decoder = json::Decoder::new(json_object.unwrap());
    let locations: Vec<Geo::Location> = Decodable::decode(&mut decoder).unwrap();

    println!("Decoded locations:");
    for location in locations.iter() {
        println!("  {}", location);
    }

    let mut stdwriter = stdio::stdout();
    {
//         let mut encoder = json::Encoder::new(&mut stdwriter);
        let mut encoder = json::PrettyEncoder::new(&mut stdwriter);
        locations.encode(&mut encoder).unwrap();
    }
    stdwriter.write_line("").unwrap();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions