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)