Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created August 12, 2019 06:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rust-play/9b109f5ba7ead27f76f235e705117f62 to your computer and use it in GitHub Desktop.
Save rust-play/9b109f5ba7ead27f76f235e705117f62 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, Clone)]
struct Node {
value: String,
next: Link,
prev: Link,
}
impl Node {
fn new(value: String) -> Rc<RefCell<Node>> {
Rc::new(RefCell::new(Node {
value: value,
next: None,
prev: None,
}))
}
}
type Link = Option<Rc<RefCell<Node>>>;
#[derive(Debug, Clone)]
struct BetterTransactionLog {
head: Link,
tail: Link,
pub length: u64,
}
impl BetterTransactionLog {
pub fn new_empty() -> Self {
Self {
head: None,
tail: None,
length: 0,
}
}
pub fn append(&mut self, value: String) {
let new = Node::new(value);
match self.tail.take() {
Some(old) => old.borrow_mut().next = Some(new.clone()),
None => self.head = Some(new.clone()),
}
self.length += 1;
self.tail = Some(new);
}
pub fn pop(&mut self) -> Option<String> {
self.head.take().map(|head| {
if let Some(next) = head.borrow_mut().next.take() {
// more than one elements in the list
self.head = Some(next);
} else {
// only 1 element in the list
self.tail.take();
}
self.length -= 1;
Rc::try_unwrap(head).ok().expect("BOOM!").into_inner().value
})
}
pub fn iter(&self) -> ListIterator {
ListIterator { current: self.head.clone() }
}
}
pub struct ListIterator {
current: Link,
}
impl ListIterator {
fn new(start_at: Link) -> Self {
Self { current: start_at }
}
}
impl Iterator for ListIterator {
type Item = String;
fn next(&mut self) -> Option<String> {
let mut result = None;
self.current = match self.current {
Some(ref current) => {
result = Some(current.borrow().value.clone());
current.borrow().next.clone()
},
None => None
};
result
}
}
impl DoubleEndedIterator for ListIterator{
fn next_back(&mut self) -> Option<String>{
let mut result = None;
self.current = match self.current {
Some(ref current) => {
result = Some(current.borrow().value.clone());
current.borrow().prev.clone()
},
None => None
};
result
}
}
fn main() {
let items = vec!["one".to_string(), "two".to_string(), "three".to_string()];
let mut list = BetterTransactionLog::new_empty();
for item in items{
list.append(item);
}
for item in list.iter(){
println!("item: {:?}", item);
}
for item in list.iter(){
println!("rev item: {:?}", item);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment