Skip to content

Instantly share code, notes, and snippets.

@jcbritobr
Created October 10, 2020 21:18
Show Gist options
  • Save jcbritobr/56c1893a793e358ac327bc63228d2f48 to your computer and use it in GitHub Desktop.
Save jcbritobr/56c1893a793e358ac327bc63228d2f48 to your computer and use it in GitHub Desktop.
Linked list with tail in rust
use std::{cell::RefCell, rc::Rc};
type SingLink = Option<Rc<RefCell<Node>>>;
#[derive(Clone)]
struct Node {
value: String,
next: SingLink,
}
impl Node {
fn new(str: String) -> Rc<RefCell<Node>> {
Rc::new(RefCell::new(Node {
value: str,
next: None,
}))
}
}
struct TransactionLog {
head: SingLink,
tail: SingLink,
length: u64,
}
impl TransactionLog {
fn new_empty() -> TransactionLog {
TransactionLog {
head: None,
tail: None,
length: 0,
}
}
fn push_back(&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);
}
fn pop(&mut self) -> Option<String> {
self.head.take().map(|head| {
if let Some(next) = head.borrow_mut().next.take() {
self.head = Some(next);
} else {
self.tail.take();
}
self.length -= 1;
Rc::try_unwrap(head)
.ok()
.expect("failt to remove entry")
.into_inner()
.value
})
}
}
fn main() {
let mut log = TransactionLog::new_empty();
log.push_back("entry log 1".to_string());
log.push_back("entry log 2".to_string());
println!("{}", log.pop().expect("no value"));
println!("{}", log.pop().expect("no value"));
println!("{}", log.pop().expect("no value"));
println!("finnish");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment