Pregunta

In Rust 0.9, I found a way to read the values out of a JSON enum. However, I'm struggling to figure this out in the current Rust 0.10 nightly. Ideally, I'd just like to read out a value from a Json enum, but if using a predefined struct is the only way that's fine too.

Here's what used to work:

extern mod extra;

fn main() {
  let json = extra::json::from_str(json_str).unwrap();
  let (lat, long): (f32, f32) = match json {
    Object(o) => { 
      let lat = o.find(&~"latitude").unwrap();
      let lat2 = lat.to_str();
      let lat3: Option<f32> = from_str(lat2);

      let longJson = o.find(&~"longitude").unwrap();
      let longStr = longJson.to_str();
      let long: Option<f32> = from_str(longStr);

      (lat3.unwrap(), long.unwrap())
    }
    _ => { (0.0,0.0) }
  };

  println(lat.to_str());
  println(long.to_str());
}

The variable json_str should actually be defined above, but I'm putting here for legibility:

{
  'timezone': 'America/Los_Angeles',
  'isp': 'Monkey Brains',
  'region_code': 'CA',
  'country': 'United States',
  'dma_code': '0',
  'area_code': '0',
  'region': 'California',
  'ip': '199.116.73.2',
  'asn': 'AS32329',
  'continent_code': 'NA',
  'city': 'San Francisco',
  'longitude': - 122.4194,
  'latitude': 37.7749,
  'country_code': 'US',
  'country_code3': 'USA'
}

I found this Json example from the nightly documentation but it seems like a lot of boilerplate. Is there no way to just read out a few values like in older code example? Thanks!!

¿Fue útil?

Solución

It is almost the same thing, only some function names have changed. Here is a working code:

extern crate serialize;

use serialize::json;

static json_str: &'static str = r#"
{
  "timezone": "America/Los_Angeles",
  "isp": "Monkey Brains",
  "region_code": "CA",
  "country": "United States",
  "dma_code": "0",
  "area_code": "0",
  "region": "California",
  "ip": "199.116.73.2",
  "asn": "AS32329",
  "continent_code": "NA",
  "city": "San Francisco",
  "longitude": -122.4194,
  "latitude": 37.7749,
  "country_code": "US",
  "country_code3": "USA"
}
"#; 

fn main() {
  let json = json::from_str(json_str);
  let (lat, long): (f32, f32) = match json {
    Ok(json::Object(o)) => { 
      let lat = o.find(&~"latitude").unwrap();
      let latOpt: Option<f64> = lat.as_number();

      let long = o.find(&~"longitude").unwrap();
      let longOpt: Option<f64> = long.as_number();

      (latOpt.unwrap() as f32, longOpt.unwrap() as f32)
    }
    Err(e) => fail!("Error decoding: {}", e),
    _ => { (0.0,0.0) }
  };

  println!("{}", lat.to_str());
  println!("{}", long.to_str());
}

Note that I had to change your JSON object slightly because it is not valid - it uses ' instead of " for strings and also there is an error in longitude (- and the number itself are separated by space).

Another slight change is that there is no need to perform string conversions to obtain a number. Json enum has as_number() method which returns Option<f64>. You can cast f64 to f32, if needed.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top