Search code examples
rustnetcdf

Deconstructing enums in Rust


Very new to rust and trying to understand how to idiomatically work with this enum: https://docs.rs/netcdf/latest/netcdf/attribute/enum.AttrValue.html

How do I write a function that, given the netcdf::attribute::AttrValue enum and variant I expect I'm in, returns to me the primitive that the enum variant was constructed from? Something about deconstruction and generic functions, but I can't get a nice solution off the ground. Here's my best attempt:

use netcdf;
use std::env;

fn main() -> Result<(), netcdf::error::Error> {
    let args: Vec<String> = env::args().collect();
    let file = netcdf::open(&args[1])?; // data/CCMP_Wind_Analysis_19930103_V03.0_L4.0.nc
  
    let vwnd = &file.variable("vwnd").expect("Could not find variable 'vwnd'");
  
    // help me re-write this hacky block in a nice function that works for any variant:

    let mut units: String = String::from("null");
    let x = vwnd.attribute("units").unwrap().value().unwrap(); // here's the AttrValue enum
    if let netcdf::attribute::AttrValue::Str(v) = x {
        units = v;
    }
    println!("{}",units);

    // hack block complete    

    return Ok(())

}

This works - units does in fact have a String-type string in it - but this seems very not idiomatic. How should I turn this into an idiomatic rust function?


Solution

  • You would normally use the TryFrom trait for this. If the library author had provided TryFrom instances for his type, then you could simply write String::try_from(v) and get either an Ok(string) or an appropriate error.

    Unfortunately, they didn't do so. You can always do it yourself with the newtype pattern, but it'll be a decent bit of legwork to get all of those types up and running.