Return and use a generic match type

I am working on a simple Rust application that accepts stdin and acts on its basis. I would like each team to return a vector of results.

Different commands can return different input vectors; the method listreturns the vector PathBufs, but the match command returns strings by default:

use std::{io, fs};
use std::path::PathBuf;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let chars_to_trim: &[char] = &['\n'];
    let trimmed_input: &str = input.trim_matches(chars_to_trim);

    let no_match = vec!["No Match"];

    let result = match trimmed_input {
        "list" => list(),
        _ => no_match,
    };
}

fn list() -> Vec<PathBuf> {
    println!("{}", "list of lockfiles here");
    let entries = fs::read_dir("/tmp").expect("Failed to read /tmp");
    let all: Result<_, _> = entries.map(|entry| entry.map(|e| e.path())).collect();
    all.expect("Unable to read an entry")
}

This will cause compilation to fail:

error[E0308]: match arms have incompatible types
  --> src/main.rs:12:22
   |
12 |         let result = match trimmed_input {
   |                      ^ expected struct `std::path::PathBuf`, found &str
   |
   = note: expected type `std::vec::Vec<std::path::PathBuf>`
   = note:    found type `std::vec::Vec<&str>`
note: match arm with an incompatible type
  --> src/main.rs:14:18
   |
14 |             _ => no_match,
   |                  ^^^^^^^^

What is the idiomatic way of rust? I read the generics documentation, but I'm not sure how to apply it.

+4
source share
1 answer

Here is the test:

use std::path::PathBuf;

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result = match 1 {
        1 => paths,
        _ => defaults,
    };
}

, Rust , . , .

, , enum, , :

use std::path::PathBuf;

enum MyThing<'a> {
    Str(&'a str),
    Path(PathBuf),
}

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(MyThing::Path).collect(),
        _ => defaults.into_iter().map(MyThing::Str).collect(),
    };
}

, , String:

use std::path::PathBuf;

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(|p| p.to_string_lossy().into_owned()).collect(),
        _ => defaults.into_iter().map(|s| s.to_string()).collect(),
    };
}

- . -. , . , :

use std::path::PathBuf;

trait MyTrait {
    fn size(&self) -> u8;
}

impl MyTrait for PathBuf {
    fn size(&self) -> u8 {
        15
    }
}

impl<'a> MyTrait for &'a str {
    fn size(&self) -> u8 {
        88
    }
}

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(|p| Box::new(p) as Box<MyTrait>).collect(),
        _ => defaults.into_iter().map(|s| Box::new(s) as Box<MyTrait>).collect(),
    };
}
+6

All Articles