### Handle Binary and BitBinary Data Source: https://context7.com/sile/eetf/llms.txt Provides examples for standard byte-aligned Binaries and BitBinaries, which allow for bit-level granularity in data representation. ```rust use eetf::{Term, Binary, BitBinary}; use std::io::Cursor; // Create binary from bytes let binary = Binary::from(vec![1, 2, 3, 4]); // Encode binary data let mut buf = Vec::new(); Term::from(Binary::from(vec![1, 2, 3])).encode(&mut buf).unwrap(); // BitBinary for non-byte-aligned data let bit_binary = BitBinary::from((vec![1, 2, 3], 5)); // 3 bytes, last has 5 bits assert_eq!("<<1,2,3:5>>", bit_binary.to_string()); // Decode binary let bytes = vec![131, 109, 0, 0, 0, 3, 1, 2, 3]; let decoded: Binary = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.bytes, vec![1, 2, 3]); ``` -------------------------------- ### Manage Erlang Process Identifiers, Ports, and References Source: https://context7.com/sile/eetf/llms.txt Demonstrates how to instantiate and display Erlang-style PIDs, ports, and references. These types are essential for distributed system communication and can be encoded into binary formats. ```rust use eetf::{Term, Pid, Port, Reference}; use std::io::Cursor; // Create a PID let pid = Pid::new("nonode@nohost", 49, 0, 0); // Or using tuple conversion let pid_tuple = Pid::from(("nonode@nohost", 49, 0)); // Create a Port let port = Port::from(("nonode@nohost", 366)); // Create a Reference let reference = Reference::from(("nonode@nohost", 123)); let multi_id_ref = Reference::from(("nonode@nohost", vec![138016, 262145, 0])); // Encode process identifiers let mut pid_buf = Vec::new(); Term::from(pid.clone()).encode(&mut pid_buf).unwrap(); // Display formats assert_eq!(r#"<'nonode@nohost'.49.0>"#, pid.to_string()); assert_eq!(r#"#Port<'nonode@nohost'.366>"#, port.to_string()); assert_eq!(r#"#Ref<'nonode@nohost'.123>"#, reference.to_string()); ``` -------------------------------- ### Work with Erlang Tuples Source: https://context7.com/sile/eetf/llms.txt Shows how to create fixed-size containers for structured data and how to access elements after decoding. ```rust use eetf::{Term, Tuple, Atom, FixInteger}; use std::io::Cursor; // Create tuples let tuple = Tuple::from(vec![ Term::from(Atom::from("ok")), Term::from(FixInteger::from(42)) ]); // Encode a tuple let mut buf = Vec::new(); let response = Term::from(Tuple::from(vec![ Term::from(Atom::from("error")), Term::from(Atom::from("not_found")) ])); response.encode(&mut buf).unwrap(); // Decode and access tuple elements let bytes = vec![131, 104, 2, 100, 0, 1, 97, 97, 1]; // {a, 1} let decoded: Tuple = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.elements.len(), 2); ``` -------------------------------- ### Handle Floating Point Numbers with EETF Source: https://context7.com/sile/eetf/llms.txt Demonstrates creating, encoding, and decoding 64-bit floating point numbers. Note that EETF requires finite values and will reject NaN or Infinity. ```rust use eetf::{Term, Float}; use std::io::Cursor; use std::convert::TryFrom; // Create floats (must be finite) let f = Float::try_from(123.456).unwrap(); let negative = Float::try_from(-99.9).unwrap(); // Non-finite values are rejected assert!(Float::try_from(f64::NAN).is_err()); assert!(Float::try_from(f64::INFINITY).is_err()); // Encode and decode floats let mut buf = Vec::new(); Term::from(Float::try_from(123.456).unwrap()).encode(&mut buf).unwrap(); assert_eq!(vec![131, 70, 64, 94, 221, 47, 26, 159, 190, 119], buf); let bytes = vec![131, 70, 64, 94, 221, 47, 26, 159, 190, 119]; let decoded: Float = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.value, 123.456); ``` -------------------------------- ### Implement Erlang Maps Source: https://context7.com/sile/eetf/llms.txt Demonstrates using key-value structures where keys and values can be any valid EETF term. Supports initialization from arrays or standard HashMaps. ```rust use eetf::{Term, Map, Atom, FixInteger}; use std::collections::HashMap; use std::io::Cursor; // Create maps using array syntax let map = Map::from([ (Term::from(Atom::from("name")), Term::from(Atom::from("alice"))), (Term::from(Atom::from("age")), Term::from(FixInteger::from(30))) ]); // Create from HashMap let mut hash_map = HashMap::new(); hash_map.insert(Term::from(Atom::from("key")), Term::from(FixInteger::from(1))); let map_from_hash = Map::from(hash_map); // Encode and decode maps let mut buf = Vec::new(); Term::from(map.clone()).encode(&mut buf).unwrap(); let bytes = vec![131, 116, 0, 0, 0, 2, 97, 1, 97, 2, 100, 0, 1, 97, 100, 0, 1, 98]; let decoded: Map = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); ``` -------------------------------- ### Convert Between Term Variants and Rust Types Source: https://context7.com/sile/eetf/llms.txt Demonstrates the use of conversion traits to transform EETF terms into native Rust types. Includes borrowing, numeric conversions, and consuming conversions. ```rust use eetf::{Term, Atom, FixInteger, BigInteger, Float, List}; use eetf::convert::TryAsRef; use num_traits::ToPrimitive; use num_bigint::ToBigInt; // TryAsRef for borrowing inner types let term = Term::from(Atom::from("hello")); if let Some(atom) = term.try_as_ref() as Option<&Atom> { println!("Atom name: {}", atom.name); } // ToPrimitive for numeric conversions let fix_int = FixInteger::from(42); assert_eq!(fix_int.to_i64(), Some(42i64)); assert_eq!(fix_int.to_f64(), Some(42.0)); let big_int = BigInteger::from(1000000000000i64); assert_eq!(big_int.to_i64(), Some(1000000000000i64)); // ToBigInt for arbitrary precision let term_int = Term::from(FixInteger::from(100)); let big = term_int.to_bigint().unwrap(); // TryInto for consuming conversions let term = Term::from(FixInteger::from(5)); let fix: Result = term.try_into(); assert_eq!(fix.unwrap().value, 5); ``` -------------------------------- ### Handle Decode and Encode Errors in Rust Source: https://context7.com/sile/eetf/llms.txt Demonstrates how to catch and handle specific error variants when decoding binary data or encoding Rust types into the Erlang External Term Format. It covers common failure scenarios such as unsupported versions, unknown tags, IO errors, and data size constraints. ```rust use eetf::{Term, Atom, BigInteger, DecodeError, EncodeError}; use std::io::Cursor; // DecodeError variants let bad_version = vec![255, 0, 0]; // Invalid version byte match Term::decode(Cursor::new(&bad_version)) { Err(DecodeError::UnsupportedVersion { version }) => { println!("Unsupported version: {}", version); } Err(DecodeError::UnknownTag { tag }) => { println!("Unknown tag: {}", tag); } Err(DecodeError::Io(e)) => { println!("IO error: {}", e); } Err(DecodeError::UnexpectedType { value, expected }) => { println!("Expected {}, got {}", expected, value); } _ => {} } // EncodeError for oversized data let long_atom_name = "x".repeat(70000); // Exceeds max atom length let atom = Atom::from(long_atom_name); let mut buf = Vec::new(); match Term::from(atom).encode(&mut buf) { Err(EncodeError::TooLongAtomName(atom)) => { println!("Atom name too long: {} bytes", atom.name.len()); } Err(EncodeError::TooLargeInteger(int)) => { println!("Integer too large to encode"); } Err(EncodeError::Io(e)) => { println!("IO error: {}", e); } _ => {} } ``` -------------------------------- ### Handle External and Internal Function References Source: https://context7.com/sile/eetf/llms.txt Shows how to represent and manipulate Erlang function references. This includes external functions (module:function/arity) and internal closures containing captured variables. ```rust use eetf::{Term, ExternalFun, InternalFun, Atom, Pid, FixInteger}; use std::io::Cursor; // External function reference (fun module:function/arity) let ext_fun = ExternalFun::from(("lists", "map", 2)); assert_eq!(r#"fun 'lists':'map'/2"#, ext_fun.to_string()); // Encode external function let mut buf = Vec::new(); Term::from(ExternalFun::from(("foo", "bar", 3))).encode(&mut buf).unwrap(); // Decode external function let bytes = vec![131, 113, 100, 0, 3, 102, 111, 111, 100, 0, 3, 98, 97, 114, 97, 3]; let decoded: ExternalFun = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.module.name, "foo"); assert_eq!(decoded.function.name, "bar"); assert_eq!(decoded.arity, 3); // Internal functions (closures) contain captured variables let internal = InternalFun::New { module: Atom::from("mymodule"), arity: 1, pid: Pid::from(("nonode@nohost", 36, 0)), index: 0, uniq: [0; 16], old_index: 0, old_uniq: 0, free_vars: vec![Term::from(FixInteger::from(10))], }; ``` -------------------------------- ### Manage Erlang List Types Source: https://context7.com/sile/eetf/llms.txt Covers the creation and manipulation of proper lists, improper lists, and optimized ByteLists. These types are essential for representing Erlang list structures in Rust. ```rust use eetf::{Term, List, ImproperList, ByteList, Atom, FixInteger}; use std::io::Cursor; // Create proper lists let list = List::from(vec![ Term::from(Atom::from("a")), Term::from(FixInteger::from(1)) ]); // Empty list (nil) let nil = List::nil(); assert!(nil.is_nil()); // Improper lists (tail is not nil) let improper = ImproperList::from(( vec![Term::from(Atom::from("a"))], Term::from(FixInteger::from(1)) // tail )); // ByteList for efficient string/byte representation let byte_list = ByteList::from("hello"); let byte_list_raw = ByteList::from(vec![1, 2, 3]); // Encode a list let mut buf = Vec::new(); Term::from(List::from(vec![Term::from(Atom::from("a"))])).encode(&mut buf).unwrap(); // Decode a list let bytes = vec![131, 108, 0, 0, 0, 1, 100, 0, 1, 97, 106]; let decoded: List = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); ``` -------------------------------- ### Perform Erlang-style Pattern Matching Source: https://context7.com/sile/eetf/llms.txt Utilizes the pattern module to extract and validate data from terms. Supports matching atoms, tuples, typed values, and variable-length lists. ```rust use eetf::{Term, Atom, Tuple, FixInteger, List}; use eetf::pattern::{any, U8, VarList, Or, Union2}; // Match an atom by name let term = Term::from(Atom::from("ok")); term.as_match("ok").unwrap(); // Succeeds assert!(term.as_match("error").is_err()); // Fails // Extract typed values using any() let tuple_term = Term::from(Tuple::from(vec![ Term::from(Atom::from("user")), Term::from(Atom::from("alice")), ])); let (_, name) = tuple_term.as_match(("user", any::())).unwrap(); assert_eq!(name.name, "alice"); // Match tuples with specific patterns let response = Term::from(Tuple::from(vec![ Term::from(Atom::from("ok")), Term::from(FixInteger::from(42)), ])); let (_, value) = response.as_match(("ok", any::())).unwrap(); assert_eq!(value.value, 42); // Match integers with type constraints let num = Term::from(FixInteger::from(8)); let byte_val = num.as_match(U8).unwrap(); assert_eq!(byte_val, 8u8); // Match variable-length lists let list = Term::from(List::from(vec![ Term::from(FixInteger::from(1)), Term::from(FixInteger::from(2)), Term::from(FixInteger::from(3)), ])); let values = list.as_match(VarList(U8)).unwrap(); assert_eq!(values, vec![1u8, 2, 3]); ``` -------------------------------- ### Term::decode - Decode Erlang Binary to Term (Rust) Source: https://context7.com/sile/eetf/llms.txt Decodes a byte stream containing Erlang External Term Format data into a Rust `Term` enum. The decoder automatically handles version headers, compression, and all supported term types. It takes a `Cursor` as input and returns a `Result`. ```rust use std::io::Cursor; use eetf::{Term, Atom}; // Decode an atom from raw bytes // Byte format: [131 (version), 119 (small_atom_utf8), 3 (length), 'f', 'o', 'o'] let bytes = vec![131, 119, 3, 102, 111, 111]; let term = Term::decode(Cursor::new(&bytes)).unwrap(); assert_eq!(term, Term::from(Atom::from("foo"))); // Decode a tuple containing multiple terms let tuple_bytes = vec![131, 104, 2, 119, 1, 97, 97, 1]; // {a, 1} let tuple_term = Term::decode(Cursor::new(&tuple_bytes)).unwrap(); // Result: Tuple containing Atom("a") and FixInteger(1) // Decode a list let list_bytes = vec![131, 108, 0, 0, 0, 1, 100, 0, 1, 97, 106]; // [a] let list_term = Term::decode(Cursor::new(&list_bytes)).unwrap(); // Handle decoding errors let invalid_bytes = vec![255, 0, 0]; // Invalid version match Term::decode(Cursor::new(&invalid_bytes)) { Ok(_) => println!("Decoded successfully"), Err(e) => println!("Decode error: {:?}", e), } ``` -------------------------------- ### Term::encode - Encode Term to Erlang Binary (Rust) Source: https://context7.com/sile/eetf/llms.txt Encodes a Rust `Term` into the Erlang External Term Format byte representation. The encoder automatically selects the most efficient encoding for each term type. It takes a mutable byte vector (`Vec`) as an argument to write the encoded data and returns a `Result<(), Error>`. ```rust use eetf::{Term, Atom, FixInteger, Tuple, List}; // Encode an atom let mut buf = Vec::new(); let term = Term::from(Atom::from("foo")); term.encode(&mut buf).unwrap(); assert_eq!(vec![131, 119, 3, 102, 111, 111], buf); // Encode an integer let mut int_buf = Vec::new(); Term::from(FixInteger::from(1000)).encode(&mut int_buf).unwrap(); assert_eq!(vec![131, 98, 0, 0, 3, 232], int_buf); // Encode a tuple {ok, 42} let mut tuple_buf = Vec::new(); let tuple = Term::from(Tuple::from(vec![ Term::from(Atom::from("ok")), Term::from(FixInteger::from(42)) ])); tuple.encode(&mut tuple_buf).unwrap(); // Encode a list [1, 2, 3] let mut list_buf = Vec::new(); let list = Term::from(List::from(vec![ Term::from(FixInteger::from(1)), Term::from(FixInteger::from(2)), Term::from(FixInteger::from(3)) ])); list.encode(&mut list_buf).unwrap(); ``` -------------------------------- ### Atom - Erlang Atom Type Representation (Rust) Source: https://context7.com/sile/eetf/llms.txt Represents an Erlang atom, which is a named constant. Atoms are created from strings and support UTF-8 encoding. This type can be converted to and from `Term` for encoding and decoding purposes. ```rust use eetf::{Term, Atom}; use std::io::Cursor; // Create atoms from strings let atom = Atom::from("hello"); let atom_owned = Atom::from(String::from("world")); // Convert atom to Term for encoding/decoding let term = Term::from(Atom::from("ok")); // Decode an atom and access its name let bytes = vec![131, 119, 5, 104, 101, 108, 108, 111]; // 'hello' let decoded: Atom = Term::decode(Cursor::new(&bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.name, "hello"); // Display format includes single quotes assert_eq!("'foo'", Atom::from("foo").to_string()); assert_eq!(r"'fo\'o'", Atom::from(r"fo'o").to_string()); // Escaped quotes ``` -------------------------------- ### FixInteger and BigInteger - Erlang Integer Types (Rust) Source: https://context7.com/sile/eetf/llms.txt `FixInteger` handles 32-bit signed integers, while `BigInteger` supports arbitrary precision integers using the `num-bigint` crate. Both can be encoded to and decoded from Erlang External Term Format. ```rust use eetf::{Term, FixInteger, BigInteger}; use std::io::Cursor; // Fixed-width integers (i32 range) let small = FixInteger::from(42i32); let negative = FixInteger::from(-1000i32); // Encode small integers efficiently let mut buf = Vec::new(); Term::from(FixInteger::from(10)).encode(&mut buf).unwrap(); assert_eq!(vec![131, 97, 10], buf); // SMALL_INTEGER_EXT // Big integers for values outside i32 range let big = BigInteger::from(10000000000u64); let mut big_buf = Vec::new(); Term::from(big).encode(&mut big_buf).unwrap(); // Decode integers let int_bytes = vec![131, 98, 0, 0, 3, 232]; // 1000 let decoded: FixInteger = Term::decode(Cursor::new(&int_bytes)).unwrap().try_into().unwrap(); assert_eq!(decoded.value, 1000); // Convert between integer types let fix = FixInteger::from(100); let big_from_fix = BigInteger::from(&fix); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.