BurntSushi / BurntSushi/rust-csv
How to refer to a csv::Writer without caring what it's writing to?
- Dominant language
- Rust
- Stars
- 2k
- Forks
- 257
- PR merge metrics
- No merged PRs in 30d
Description
#### What version of the `csv` crate are you using?
`csv 1.1.3`
#### Briefly describe the question, bug or feature request.
I'm trying to implement the common pattern of accepting `-` to indicate STDOUT/STDIN in CLI arguments representing paths, and running into trouble assigning either the result of a `csv::Writer::from_writer` or `csv::Writer::from_path` to the same variable.
#### Include a complete program demonstrating a problem.
[Rust playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=623dcb4007a5bcbe8905177e69f0d020)
Here's (approximately) what I want to write:
```rust
fn run(path: &str) -> Result<(), Box> {
let mut wtr = match path {
"-" => Box::new(csv::Writer::from_writer(io::stdout())),
path => Box::new(csv::Writer::from_path(path)?),
};
wtr.write_record(&["a", "b", "c"])?;
wtr.flush()?;
Ok(())
}
```
I've found an acceptable way to do it by adding some indirection:
```rust
fn run_generic_inner(mut wtr: csv::Writer) -> Result<(), Box> {
wtr.write_record(&["a", "b", "c"])?;
wtr.flush()?;
Ok(())
}
fn run_generic(path: &str) -> Result<(), Box> {
match path {
"-" => run_generic_inner(csv::Writer::from_writer(io::stdout())),
path => run_generic_inner(csv::Writer::from_path(path)?),
}
}
```
#### What is the observed behavior of the code above?
The former snippet fails to compile; the latter works correctly. The error:
```
error[E0308]: `match` arms have incompatible types
--> src/main.rs:9:17
|
7 | let mut wtr = match path {
| ___________________-
8 | | "-" => Box::new(csv::Writer::from_writer(io::stdout())),
| | ------------------------------------------------ this is found to be of type `std::boxed::Box>`
9 | | path => Box::new(csv::Writer::from_path(path)?),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::io::Stdout`, found struct `std::fs::File`
10 | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `std::boxed::Box>`
found struct `std::boxed::Box>`
```
#### What is the expected or desired behavior of the code above?
I'd like to be able to pass around a reference to a `csv::Writer` without knowing/caring what it's writing to.
One way to do this would be to add a `Writer` trait or similar, and I could accept `Box` etc. There might be something much more idiomatic.
(The code with the generic parameter is a little annoying for my use case, though workable.)
Perhaps even better, a cookbook example or even `rust-csv` support for the `-`-means-STDIN/OUT pattern.
#### P.S.
Thanks for a great library!
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.