use std::rc::Rc;
use std::cell::RefCell;
use std::mem;
struct Codec {}
type Elem = (i32, usize, usize);
type Node = Rc<RefCell<TreeNode>>;
impl Codec {
fn new() -> Self {
Codec {}
}
fn serialize(&self, root: Option<Node>) -> String {
struct Id(usize);
impl Id {
pub fn new(start: usize) -> Self {
Id(start)
}
pub fn get(&self) -> usize {
self.0
}
pub fn increase(&mut self) {
self.0 += 1;
}
}
fn count(node: Option<&Node>) -> usize {
match node {
Some(node) => {
let mut result = 1;
result += count(node.borrow().left.as_ref());
result += count(node.borrow().right.as_ref());
result
},
None => 0
}
}
fn build(node: Option<Node>, serialized: &mut Vec<Elem>, id_struct: &mut Id) -> usize {
match node {
Some(node) => {
let (id, val, mut left_id, mut right_id) = (id_struct.get(), node.borrow().val, 0, 0);
id_struct.increase();
node.borrow_mut().left.take().map(|left| {
left_id = build(Some(left), serialized, id_struct);
});
node.borrow_mut().right.take().map(|right| {
right_id = build(Some(right), serialized, id_struct);
});
serialized[id] = (val, left_id, right_id);
id
},
None => 0
}
}
let n = count(root.as_ref());
let (mut serialized, mut id_struct) = (vec![(0, 0, 0); n], Id::new(0));
build(root, &mut serialized, &mut id_struct);
unsafe {
let (og_len, og_cap, og_size) = (serialized.len(), serialized.capacity(), mem::size_of::<Elem>());
let ptr_serialized = mem::ManuallyDrop::new(serialized).as_mut_ptr();
let bytes = Vec::from_raw_parts(ptr_serialized as *mut u8, og_len * og_size, og_cap * og_size);
String::from_utf8_unchecked(bytes)
}
}
fn deserialize(&self, data: String) -> Option<Node> {
let bytes = data.into_bytes();
let serialized =
unsafe {
let (len, cap, og_size) = (bytes.len(), bytes.capacity(), mem::size_of::<Elem>());
let ptr_serialized = mem::ManuallyDrop::new(bytes).as_mut_ptr();
Vec::from_raw_parts(ptr_serialized as *mut Elem, len / og_size, cap / og_size)
};
fn build_tree(id: usize, serialized: &Vec<Elem>) -> Node {
let (val, left_id, right_id) = serialized[id];
let mut node = TreeNode::new(val);
if left_id != 0 {
node.left = Some(build_tree(left_id, serialized));
}
if right_id != 0 {
node.right = Some(build_tree(right_id, serialized));
}
Rc::new(RefCell::new(node))
}
if serialized.len() > 0 {
Some(build_tree(0, &serialized))
} else {
None
}
}
}