7 releases (stable)
| 1.1.28 | Dec 10, 2025 |
|---|---|
| 1.1.5 | Oct 24, 2025 |
| 0.0.28 | Dec 10, 2025 |
| 0.0.9 |
|
| 0.0.1 |
|
#330 in Text processing
68KB
2K
SLoC
Yangon
A high-performance, stack-allocated string type for Rust with fixed capacity and zero heap allocations.
Overview
Yangon is string library that provides a stack-allocated alternative to String. By using fixed-capacity storage and const generics, Yangon eliminates heap allocations for performance-critical applications.
Highlights:
- Zero heap allocations - all data stored on the stack
- Configurable capacity via const generics
- Full UTF-8 validation and support
Installation
Add Yangon to your Cargo.toml:
[dependencies]
yangon = "0.0.3"
Quick Start
use yangon::{Yangon, yangon};
// Create with default 10KB capacity
let mut s = Yangon::new();
s.push_str("Hello, ").unwrap();
s.push_str("Yangon!").unwrap();
println!("{}", s); // "Hello, Yangon!"
// Or use the macro
let s = yangon!("Hello, World!");
// Custom capacity with const generics
let mut small: Yangon<64> = Yangon::with_capacity();
small.push_str("Small buffer").unwrap();
Key Features
Stack Allocation
- No heap allocations - all string data lives on the stack
- Predictable memory usage - capacity known at compile time
- Default 10KB capacity when using
Yangon::new()orYangon::from() - Configurable via const generics -
Yangon<N>where N is byte capacity
String-Like API
Yangon provides familiar methods similar to String:
let mut s = yangon!("Hello");
// Push operations
s.push_str(" World").unwrap();
s.push('!').unwrap();
// Modification
s.insert(5, ',');
s.remove(5);
s.pop();
s.clear();
s.truncate(5);
// Inspection
assert_eq!(s.len(), 5);
assert!(!s.is_empty());
assert_eq!(s.as_str(), "Hello");
Advanced Pattern Matching
Yangon's replace function supports multiple pattern types with turbo fish syntax:
let s = yangon!("Hello World");
// Replace string slice
let s1 = s.replace::<&str, 0>("World", "Yangon");
// Replace single character
let s2 = s.replace::<char, 0>('o', "0");
// Replace multiple characters
let s3 = s.replace::<_, 2>(&['H', 'W'], "X");
// Replace with closure (e.g., remove whitespace)
let s4 = s.replace::<fn(char) -> bool, 0>(|c| c.is_whitespace(), "");
UTF-8 Handling
Full UTF-8 support with validation:
use yangon::Yangon;
// From valid UTF-8
let s = Yangon::from_utf8(vec![72, 101, 108, 108, 111]).unwrap();
// Unchecked (unsafe but faster)
let s = unsafe { Yangon::from_utf8_unchecked(vec![72, 101, 108, 108, 111]) };
// Lossy conversion (replaces invalid sequences with �)
let bytes = vec![0xFF, 0xFE, 72, 105];
let s = Yangon::from_utf8_lossy(&bytes);
Iteration and Collection
use yangon::Yangon;
// From iterator
let chars = vec!['H', 'e', 'l', 'l', 'o'];
let s: Yangon = chars.into_iter().collect();
// Retain with predicate
let mut s = yangon!("Hello123World");
s.retain(|c| c.is_alphabetic());
assert_eq!(s, "HelloWorld");
Additional Operations
let mut s = yangon!(" Hello World ");
// Trimming (returns &str)
assert_eq!(s.trim(), "Hello World");
// Split off at index
let s2 = s.split_off(7);
// Replace range
s.replace_range(0..5, "Hi");
// Convert to bytes
let bytes: Vec<u8> = s.into_bytes();
// Convert to String
let string: String = s.to_string();
Use Cases
Yangon is ideal for:
- Performance-critical code where heap allocation overhead is unacceptable
- Network protocols requiring fixed-size string buffers
- Data transfer/storage with known maximum string lengths
- Real-time applications requiring predictable performance
Performance Considerations
When Yangon Excels
push_stroperations: ~15x faster thanStringpushoperations: Significantly faster- Character-by-character building: Minimal allocation overhead
- Short to medium strings fitting in capacity
Performance Notes
replacefunction is slower thanString::replace- avoid in hot paths when possible- Best for data transfer and storage; consider
Stringfor highly dynamic string manipulation
Safety
Yangon uses unsafe internally for performance-critical operations but maintains safety guarantees:
- UTF-8 validation on all public APIs (except
_uncheckedvariants) - Bounds checking prevents invalid memory access
_uncheckedvariants assume valid input for maximum performance
API Conversion Reference
| String Method | Yangon Equivalent | Returns |
|---|---|---|
String::new() |
Yangon::new() |
Yangon |
String::from(s) |
Yangon::from(s) |
Yangon |
s.push_str(s) |
s.push_str(s) |
Result<(), yError> |
s.push(c) |
s.push(c) |
Result<(), yError> |
s.as_str() |
s.as_str() |
&str |
String::from_utf8(v) |
Yangon::from_utf8(v) |
Result<Yangon, yError> |
String::from_utf8_lossy(v) |
Yangon::from_utf8_lossy(v) |
yCow<Yangon> |
Traits Implemented
Display- Format for printingDebug- Debug formattingWrite- Format writing supportDeref<Target = str>- Automatic coercion to&strAsRef<str>- Borrow as string slicePartialEq<&str>- Compare with string slicesFromIterator<char>- Build from character iteratorClone- Deep copy support
Error Handling
use yangon::yError;
match s.push_str("test") {
Ok(()) => println!("Success"),
Err(yError::CapacityOverflow) => println!("Buffer full!"),
Err(yError::FromUtf8Error) => println!("Invalid UTF-8"),
}
Macro Usage
The yangon! macro provides convenient initialization:
// Empty Yangon
let empty = yangon!();
// With initial content
let s = yangon!("Hello, World!");
// Note: Only accepts 0 or 1 string literal
Documentation
Full API documentation is coming soon to docs.rs.
License
This project is licensed under the MIT License - see the LICENSE file for details.