Skip to content

Instantly share code, notes, and snippets.

@taqtiqa-mark
Forked from nyinyithann/newtype_pattern.rs
Created March 31, 2022 06:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taqtiqa-mark/a8677c1b30e1dcbcc6a2f29c677e7346 to your computer and use it in GitHub Desktop.
Save taqtiqa-mark/a8677c1b30e1dcbcc6a2f29c677e7346 to your computer and use it in GitHub Desktop.
The newtype pattern with Deref/DerefMut trait implementation
/*
To implement a trait on a type, the trait or the type has to be local to the code you work on. It is called the orphan rule.
To get around this restriction, we can use the newtype pattern which involves creating a new type in a tuple struct.
Both Vec<T> and Display trait are from the standard library and neither is local to our code.
We are not able to implement Display trait to Vec<T>. But we can construct a wrapper type holding an instance of Vec<T> and implement Display trait on it.
In the following example, VecWrapper<T> struct wraps Vec<T> and implements Display trait.
To get all the methods of Vec<T> available to VecWrapper, Deref trait is implemented on it.
ref: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html?search=borrow%20and%20asref
*/
use std::fmt::{Debug, Display, Formatter, Result};
use std::ops::{Deref, DerefMut};
fn main() {
let mut v = VecWrapper::<i32>::new();
v.push(1);
v.push(2);
v.push(3);
println!("{}", v);
}
#[derive(Debug)]
pub struct VecWrapper<T>(Vec<T>);
impl<T: Debug> VecWrapper<T> {
pub fn new() -> VecWrapper<T> {
VecWrapper(Vec::<T>::new())
}
pub fn with_capacity(capacity: usize) -> VecWrapper<T> {
VecWrapper(Vec::<T>::with_capacity(capacity))
}
}
impl<T: Debug> Default for VecWrapper<T> {
fn default() -> VecWrapper<T> {
VecWrapper::new()
}
}
impl<T: Debug> Display for VecWrapper<T> {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{:?}", self.0)
}
}
impl<T: Debug> Deref for VecWrapper<T> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> {
&self.0
}
}
impl<T: Debug> DerefMut for VecWrapper<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment