BigONotation
BigONotation

Reputation: 4538

Parsing yaml in Rust using serde_yaml

I am new to Rust. I am trying to parse yaml in Rust using serde_yaml, but can't make the code compile:

My Cargo.toml:

[package]
name = "apmdeps"
version = "0.1.0"
authors = ["Roger Rabbit"]
edition = "2018"

[dependencies]
git2 = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"

I tried to adapt the code sample found on the serde_yaml website, to no avail:

use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Dependency {
    url: String,
    tag: String,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Project {
    dependencies: Vec<Dependency>,
}

fn main() {
    let s = "---\ndependencies:\n--url:http://test1\ntag:tag1\n--url:http://test2\ntag:tag2";

    let project: Project = serde_yaml::from_str(&s);
}

I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:17:28
   |
17 |     let project: Project = serde_yaml::from_str(&s);
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Project`, found enum `std::result::Result`
   |
   = note: expected type `Project`
              found type `std::result::Result<_, serde_yaml::error::Error>`

Upvotes: 2

Views: 2639

Answers (1)

Florian Braun
Florian Braun

Reputation: 331

Your problem is that serde_yaml::from_str(&s) does not return a Dependency struct directly as you expect, but a Result struct.

Result structs are rust's way of error handling. Results are either Ok(value) or an Err and you need to check which one it is. Typically in a match expression. In your case the parsed dependency is wrapped in Ok(project) if parsing the string is successful.

I could get your code to compile with the following match expression:

let project_result : Result<Project, _> = serde_yaml::from_str(&s);

match project_result {
    Ok(project) => println!("dependencies = {:?}", project),
    Err(_) => println!("Error!")
}

The next problem however is that your string seemed not proper yaml, at least not as expected from serde, and I do get "Error!" from the program.

I changed your string to the following to get some useful output. I don't know if that is your intended yaml though.

let s = "---\ndependencies:\n - {url: http://test1, tag: tag1}\n - {url: http://test2, tag: tag2}\n";

Upvotes: 5

Related Questions