1pub mod default_formats;
4
5pub use self::default_formats::PlainBytes;
6pub use self::default_formats::PlainUtf8;
7
8use std::io::{Cursor, BufReader, BufWriter, Read, Write};
9
10#[allow(clippy::wrong_self_convention)]
38pub trait FileFormat<T> {
39 type FormatError: std::error::Error;
41
42 fn from_reader<R: Read>(&self, reader: R) -> Result<T, Self::FormatError>;
47
48 #[inline]
53 fn from_reader_buffered<R: Read>(&self, reader: R) -> Result<T, Self::FormatError> {
54 self.from_reader(BufReader::new(reader))
55 }
56
57 #[inline]
59 fn from_buffer(&self, buf: &[u8]) -> Result<T, Self::FormatError> {
60 self.from_reader(buf)
61 }
62
63 fn to_writer<W: Write>(&self, writer: W, value: &T) -> Result<(), Self::FormatError>;
68
69 #[inline]
74 fn to_writer_buffered<W: Write>(&self, writer: W, value: &T) -> Result<(), Self::FormatError> {
75 self.to_writer(BufWriter::new(writer), value)
76 }
77
78 fn to_buffer(&self, value: &T) -> Result<Vec<u8>, Self::FormatError> {
80 let mut buf = Cursor::new(Vec::new());
81 self.to_writer(&mut buf, value)?;
82 Ok(buf.into_inner())
83 }
84}
85
86#[allow(clippy::wrong_self_convention)]
88pub trait FileFormatUtf8<T>: FileFormat<T> {
89 fn from_string_buffer(&self, buf: &str) -> Result<T, Self::FormatError>;
91
92 fn to_string_buffer(&self, value: &T) -> Result<String, Self::FormatError>;
94}
95
96macro_rules! impl_file_format_delegate {
97 (<$Format:ident> $Type:ty) => (
98 impl<T, $Format: FileFormat<T>> FileFormat<T> for $Type {
99 type FormatError = <$Format as FileFormat<T>>::FormatError;
100
101 #[inline]
102 fn from_reader_buffered<R: Read>(&self, reader: R) -> Result<T, Self::FormatError> {
103 $Format::from_reader_buffered(self, reader)
104 }
105
106 #[inline]
107 fn from_reader<R: Read>(&self, reader: R) -> Result<T, Self::FormatError> {
108 $Format::from_reader(self, reader)
109 }
110
111 #[inline]
112 fn from_buffer(&self, buf: &[u8]) -> Result<T, Self::FormatError> {
113 $Format::from_buffer(self, buf)
114 }
115
116 #[inline]
117 fn to_writer<W: Write>(&self, writer: W, value: &T) -> Result<(), Self::FormatError> {
118 $Format::to_writer(self, writer, value)
119 }
120
121 #[inline]
122 fn to_writer_buffered<W: Write>(&self, writer: W, value: &T) -> Result<(), Self::FormatError> {
123 $Format::to_writer_buffered(self, writer, value)
124 }
125
126 #[inline]
127 fn to_buffer(&self, value: &T) -> Result<Vec<u8>, Self::FormatError> {
128 $Format::to_buffer(self, value)
129 }
130 }
131
132 impl<T, $Format: FileFormatUtf8<T>> FileFormatUtf8<T> for $Type {
133 fn from_string_buffer(&self, buf: &str) -> Result<T, Self::FormatError> {
134 $Format::from_string_buffer(self, buf)
135 }
136
137 fn to_string_buffer(&self, value: &T) -> Result<String, Self::FormatError> {
138 $Format::to_string_buffer(self, value)
139 }
140 }
141 );
142}
143
144impl_file_format_delegate!(<Format> &Format);
145impl_file_format_delegate!(<Format> std::boxed::Box<Format>);
146impl_file_format_delegate!(<Format> std::rc::Rc<Format>);
147impl_file_format_delegate!(<Format> std::sync::Arc<Format>);