Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
vojtechkral opened this issue Jun 14, 2014 · 2 comments
Closed

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

vojtechkral opened this issue Jun 14, 2014 · 2 comments

Comments

@vojtechkral
Copy link
Contributor

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();
}
@vojtechkral
Copy link
Contributor Author

Eh, never mind, it's my fault, looks like the len param of emit_struct() needs to be nonzero for PrettyEncoder.

Still, though, it would be nice if the emits behaved the same way for both encoders. To be honest, I don't quite see why emit_struct() needs name and len in the first place...

@steveklabnik
Copy link
Member

Serialize is out of tree, and it seems as though you've figured out your error, so I'm giving this a close.

bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
Insert type vars in function arguments

follow up rust-lang#14891
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants