Trait is one of powerful feature in rust. If you are coming from object oriented world, the Trait is like interface.
On of example of how we can use trait is to define abstraction for writing file. Let's create some trait code.
pub trait Buffer {
fn write(&mut self, data: &str);
}
So these buffer we will use to be an abstraction to write file.
Next, let's create BufferWritter struct for the actual implementation to the Buffer trait.
pub struct BufferWriter {
writer: BufWriter<File>,
}
impl BufferWriter {
pub fn new(file: File) -> Self {
let writer = BufWriter::new(file);
Self { writer }
}
}
And now let's implement our trait to BufferWritter.
impl Buffer for BufferWriter {
fn write(&mut self, data: &str) {
let bytes = format!("{}\n", data).as_bytes();
if let Err(e) = self.writer.write_all(bytes) {
println!("Failed to write data to file: {}", e);
}
}
}
And now let's use it to write file, first let's suppose we have some logic that made some text processing and turn it to some generated code.
pub fn write_output(buffer: Box<dyn Buffer>, config: &Config, source: &HashSet<String>) {
let mut generator = Parser::new(buffer, config.clone());
for line in source.iter() {
if generator.plugin(line).is_some() {
continue;
}
}
}
And here's our parser.
pub struct Parser {
config: Config,
writer: Box<dyn Buffer>,
}
impl Parser {
pub fn new(writer: Box<dyn Buffer>, config: Config) -> Self {
Self { config, writer }
}
pub fn plugin(&self, line: &str) {
// Some processing and then
self.writter.write(some_str);
}
}
Testing
One of the advantage of trait is for testing. In this case, we don't want to work with file directly whenever we are doing testing.
So let's take a look how we can use trait for testing.
#[test]
fn test_columns() {
let config_set = Parser::parse(include_str!("source.json")).unwrap();
let test_case = vec![
("name", "my-name"),
("wrong", "not-wrong"),
];
struct Buf(String);
impl Buffer for Buf {
fn write(&mut self, data: &str) {
assert_eq!(data, self.0)
}
}
for (class, expected) in test_case {
write_output(Box::new(Buf(expected.into())), &config_set, &set![class]);
}
}
So that it for now, if you want to read more about rust tutorial follow me at twitter @_ahmadrosid and don't forget to visit my blog ahmadrosid.com
Thank you let me know if you have any question.
Top comments (0)