Skip to content

Commit 8350604

Browse files
authored
Allow writing to io::Writer (#562)
* Allow writing to io::Writer * Add a CHANGELOG entry
1 parent da87d1c commit 8350604

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9+
### API Changes
10+
11+
- Add `ron::Options::to_io_writer` and `ron::Options::to_io_writer_pretty` to allow writing into an `io::Writer` ([#561](https://github.com/ron-rs/ron/pull/561))
12+
913
## [0.9.0] - 2025-03-18
1014

1115
### API Changes

examples/encode_file.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#![allow(dead_code)]
2+
3+
use std::{collections::HashMap, fs::File};
4+
5+
use serde::Serialize;
6+
7+
#[derive(Debug, Serialize)]
8+
struct Config {
9+
boolean: bool,
10+
float: f32,
11+
map: HashMap<u8, char>,
12+
nested: Nested,
13+
tuple: (u32, u32),
14+
vec: Vec<Nested>,
15+
}
16+
17+
#[derive(Debug, Serialize)]
18+
struct Nested {
19+
a: String,
20+
b: char,
21+
}
22+
23+
fn main() {
24+
let config = Config {
25+
boolean: true,
26+
float: 8.2,
27+
map: [(1, '1'), (2, '4'), (3, '9'), (4, '1'), (5, '2'), (6, '3')]
28+
.into_iter()
29+
.collect(),
30+
nested: Nested {
31+
a: String::from("Decode me!"),
32+
b: 'z',
33+
},
34+
tuple: (3, 7),
35+
vec: vec![
36+
Nested {
37+
a: String::from("Nested 1"),
38+
b: 'x',
39+
},
40+
Nested {
41+
a: String::from("Nested 2"),
42+
b: 'y',
43+
},
44+
Nested {
45+
a: String::from("Nested 3"),
46+
b: 'z',
47+
},
48+
],
49+
};
50+
51+
let f = File::options()
52+
.create(true)
53+
.write(true)
54+
.open("example-out.ron")
55+
.expect("Failed opening file");
56+
57+
ron::Options::default()
58+
.to_io_writer_pretty(f, &config, ron::ser::PrettyConfig::new())
59+
.expect("Failed to write to file");
60+
}

src/options.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,45 @@ impl Options {
211211
value.serialize(&mut s)
212212
}
213213

214+
/// Serializes `value` into `writer`.
215+
///
216+
/// This function does not generate any newlines or nice formatting;
217+
/// if you want that, you can use
218+
/// [`to_io_writer_pretty`][Self::to_io_writer_pretty] instead.
219+
pub fn to_io_writer<W, T>(&self, writer: W, value: &T) -> Result<()>
220+
where
221+
W: io::Write,
222+
T: ?Sized + ser::Serialize,
223+
{
224+
let mut adapter = Adapter {
225+
writer,
226+
error: Ok(()),
227+
};
228+
let result = self.to_writer(&mut adapter, value);
229+
adapter.error?;
230+
result
231+
}
232+
233+
/// Serializes `value` into `writer` in a pretty way.
234+
pub fn to_io_writer_pretty<W, T>(
235+
&self,
236+
writer: W,
237+
value: &T,
238+
config: PrettyConfig,
239+
) -> Result<()>
240+
where
241+
W: io::Write,
242+
T: ?Sized + ser::Serialize,
243+
{
244+
let mut adapter = Adapter {
245+
writer,
246+
error: Ok(()),
247+
};
248+
let result = self.to_writer_pretty(&mut adapter, value, config);
249+
adapter.error?;
250+
result
251+
}
252+
214253
/// Serializes `value` and returns it as string.
215254
///
216255
/// This function does not generate any newlines or nice formatting;
@@ -237,3 +276,21 @@ impl Options {
237276
Ok(output)
238277
}
239278
}
279+
280+
// Adapter from io::Write to fmt::Write that keeps the error
281+
struct Adapter<W: io::Write> {
282+
writer: W,
283+
error: io::Result<()>,
284+
}
285+
286+
impl<T: io::Write> fmt::Write for Adapter<T> {
287+
fn write_str(&mut self, s: &str) -> fmt::Result {
288+
match self.writer.write_all(s.as_bytes()) {
289+
Ok(()) => Ok(()),
290+
Err(e) => {
291+
self.error = Err(e);
292+
Err(fmt::Error)
293+
}
294+
}
295+
}
296+
}

0 commit comments

Comments
 (0)