use my_box::MyBox;
#[derive(Debug, Clone)]
struct Player {
name: String,
level: u32,
}
#[derive(Debug)]
struct TaskManager {
tasks: Vec<i32>,
completed: Vec<i32>,
}
impl TaskManager {
fn sort_out(&mut self) {
self.tasks.sort();
}
fn complete_task(&mut self, idx: usize) {
if idx < self.tasks.len() {
let task = self.tasks.remove(idx);
self.completed.push(task);
}
}
}
fn example_basic() {
println!("=== Example 1: Basic Heap Allocation ===");
let mut heap_num = MyBox::new(10);
*heap_num += 5;
println!(" Heap value: {}", *heap_num);
println!(" Raw pointer: {:p}", heap_num.as_ptr());
}
fn example_struct() {
println!("\n=== Example 2: Struct on the Heap ===");
let player = MyBox::new(Player {
name: String::from("MrBread"),
level: 99,
});
println!(" Player: {} (level {})", player.name, player.level);
}
fn example_mutability() {
println!("\n=== Example 3: Mutable Access via DerefMut ===");
let mut manager = MyBox::new(TaskManager {
tasks: vec![50, 10, 30, 20],
completed: vec![],
});
manager.sort_out();
println!(" Sorted tasks: {:?}", manager.tasks);
manager.complete_task(3);
println!(" Completed: {:?}", manager.completed);
println!(" Remaining: {:?}", manager.tasks);
}
fn example_clone() {
println!("\n=== Example 4: Deep Clone ===");
let original = MyBox::new(String::from("Rust Systems"));
let cloned = original.clone();
assert_eq!(*original, *cloned);
assert_eq!(original.as_str(), cloned.as_str());
assert!(original.as_ptr() != cloned.as_ptr());
println!(" Original ptr: {:p}", original.as_ptr());
println!(" Cloned ptr: {:p}", cloned.as_ptr());
println!(" Same content: {}", *original == *cloned);
println!(" Different addresses: {}", original.as_ptr() != cloned.as_ptr());
}
fn example_scoped_drop() {
println!("\n=== Example 5: Scoped Automatic Drop ===");
{
let temp = MyBox::new(vec![1, 2, 3]);
println!(" Inside scope: {:?}", *temp);
}
println!(" (temp has been dropped here)");
}
#[derive(Debug, Clone, PartialEq)]
enum LinkedList<T> {
Node { value: T, next: Box<LinkedList<T>> },
Tail,
}
impl<T> LinkedList<T> {
fn push_front(self, value: T) -> Self {
LinkedList::Node {
value,
next: Box::new(self),
}
}
fn len(&self) -> usize {
match self {
LinkedList::Node { next, .. } => 1 + next.len(),
LinkedList::Tail => 0,
}
}
}
fn example_recursive() {
println!("\n=== Example 6: Recursive Data Structure (Linked List) ===");
let list = LinkedList::Tail
.push_front(3)
.push_front(2)
.push_front(1);
println!(" List: {:?}", list);
println!(" Length: {}", list.len());
println!(
" Compile-time size of List<i32>: {}",
std::mem::size_of::<LinkedList<i32>>()
);
}
#[derive(Debug, Clone, PartialEq)]
enum JsonValue {
Null,
Bool(bool),
Number(f64),
String(String),
Array(Vec<JsonValue>),
Object(Box<[(String, JsonValue)]>),
}
impl Default for JsonValue {
fn default() -> Self {
Self::Null
}
}
fn example_json() {
println!("\n=== Example 7: Recursive Enum (JSON) ===");
let json = JsonValue::Object(Box::new([
(String::from("name"), JsonValue::String(String::from("Alice"))),
(
String::from("scores"),
JsonValue::Array(vec![
JsonValue::Number(95.0),
JsonValue::Number(87.5),
JsonValue::Number(92.0),
]),
),
(String::from("active"), JsonValue::Bool(true)),
]));
println!(" {:?}", json);
}
trait Drawable {
fn draw(&self);
fn area(&self) -> f64;
}
struct Circle {
radius: f64,
}
struct Rectangle {
width: f64,
height: f64,
}
impl Drawable for Circle {
fn draw(&self) {
println!(" Drawing Circle(r={})", self.radius);
}
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
impl Drawable for Rectangle {
fn draw(&self) {
println!(" Drawing Rectangle({} x {})", self.width, self.height);
}
fn area(&self) -> f64 {
self.width * self.height
}
}
fn example_trait_object() {
println!("\n=== Example 8: Trait Objects (dyn Drawable) ===");
let shapes: Vec<Box<dyn Drawable>> = vec![
Box::new(Circle { radius: 3.0 }),
Box::new(Rectangle {
width: 4.0,
height: 5.0,
}),
Box::new(Circle { radius: 1.5 }),
];
println!(" Shape | Area");
println!(" ------|-------");
for (_i, shape) in shapes.iter().enumerate() {
shape.draw();
println!(" => Area: {:.2}", shape.area());
assert_eq!(std::mem::size_of_val(shape), std::mem::size_of::<usize>() * 2);
}
}
#[derive(Debug, Clone)]
struct LargeData {
buffer: [u8; 4096],
index: usize,
}
impl std::ops::Deref for LargeData {
type Target = [u8; 4096];
fn deref(&self) -> &Self::Target {
&self.buffer
}
}
impl Default for LargeData {
fn default() -> Self {
Self {
buffer: [0u8; 4096],
index: 0,
}
}
}
fn example_stack_vs_heap() {
println!("\n=== Example 9: Stack vs Heap Allocation ===");
let stack_instance = LargeData {
buffer: [42; 4096],
index: 99,
};
println!(
" Stack LargeData size: {} bytes",
std::mem::size_of_val(&stack_instance)
);
let heap_instance = MyBox::new(LargeData {
buffer: [42; 4096],
index: 99,
});
println!(
" MyBox<LargeData> size: {} bytes (vs {} on stack)",
std::mem::size_of_val(&heap_instance),
std::mem::size_of_val(&stack_instance)
);
let start = std::time::Instant::now();
for _ in 0..1_000_000 {
let moved_heap = heap_instance.clone();
let _ = moved_heap.as_ptr();
}
let heap_time = start.elapsed();
println!(" 1M heap clone+move: {:?}", heap_time);
let start = std::time::Instant::now();
let stack_copy = stack_instance;
for _ in 0..1_000_000 {
let moved_stack = stack_copy.clone();
let _ = moved_stack.index;
}
let stack_time = start.elapsed();
println!(
" 1M stack clone+move: {:?} ({}x slower)",
stack_time,
stack_time.as_nanos() / heap_time.as_nanos().max(1)
);
}
fn example_raw_pointer_interop() {
println!("\n=== Example 10: Raw Pointer Interop (into_raw / from_raw) ===");
let boxed = MyBox::new(String::from("unsafe boundary"));
let ptr = boxed.into_raw();
println!(" Leaked pointer: {:p}", ptr);
assert!(!ptr.is_null());
let recovered = unsafe { MyBox::from_raw(ptr) };
assert_eq!(recovered.as_str(), "unsafe boundary");
println!(" Recovered: {}", *recovered);
println!(" (Drop runs after this scope ends)");
}
#[derive(Debug, PartialEq)]
struct Book {
title: String,
author: String,
}
fn example_collections() {
println!("\n=== Example 11: MyBox in Collections ===");
let mut library: Vec<MyBox<Book>> = vec![
MyBox::new(Book {
title: String::from("The Rust Programming Language"),
author: String::from("Klabnik & Nichols"),
}),
MyBox::new(Book {
title: String::from("Programming Rust"),
author: String::from("Jim Blandy"),
}),
MyBox::new(Book {
title: String::from("Rust for Rustaceans"),
author: String::from("Jon Gjengset"),
}),
];
println!(" Library has {} books:", library.len());
for (i, book) in library.iter().enumerate() {
println!(
" {}. \"{}\" by {}",
i + 1,
book.title,
book.author
);
}
library.sort_by(|a, b| a.title.cmp(&b.title));
println!("\n After sorting by title:");
for (i, book) in library.iter().enumerate() {
println!(" {}. \"{}\"", i + 1, book.title);
}
}
#[derive(Debug, Clone, PartialEq)]
enum BinaryTree<T> {
Leaf,
Node {
value: T,
left: Box<BinaryTree<T>>,
right: Box<BinaryTree<T>>,
},
}
impl<T> BinaryTree<T> {
fn count_nodes(&self) -> usize {
match self {
BinaryTree::Leaf => 0,
BinaryTree::Node { left, right, .. } => {
1 + left.count_nodes() + right.count_nodes()
}
}
}
}
fn example_binary_tree() {
println!("\n=== Example 12: Binary Tree with Box ===");
let tree: BinaryTree<i32> = BinaryTree::Node {
value: 10,
left: Box::new(BinaryTree::Node {
value: 5,
left: Box::new(BinaryTree::Leaf),
right: Box::new(BinaryTree::Leaf),
}),
right: Box::new(BinaryTree::Node {
value: 15,
left: Box::new(BinaryTree::Leaf),
right: Box::new(BinaryTree::Leaf),
}),
};
println!(" Tree: {:?}", tree);
println!(" Nodes: {}", tree.count_nodes());
}
fn main() {
example_basic();
example_struct();
example_mutability();
example_clone();
example_scoped_drop();
example_recursive();
example_json();
example_trait_object();
example_stack_vs_heap();
example_raw_pointer_interop();
example_collections();
example_binary_tree();
}