README

#bytes

This package provides utilities for working with sequences of bytes, offering both mutable (Bytes) and immutable (View) representations.

#Creating Bytes

You can create Bytes from various sources including arrays, fixed arrays, and iterators:

///|
test "bytes creation" {
// Create from array of bytes
let arr = [b'h', b'e', b'l', b'l', b'o']
let bytes1 = Bytes::from_array(arr)
inspect(
bytes1,
content=(
#|b"hello"
),
)

// Create from fixed array
let fixed = FixedArray::make(3, b'a')
let bytes2 = Bytes::from_array(fixed)
inspect(
bytes2,
content=(
#|b"aaa"
),
)

// Create empty bytes
let empty = (Default::default() : Bytes)
inspect(
empty,
content=(
#|b""
),
)

// Create from iterator
let iter_bytes = Bytes::from_iter(arr.iter())
inspect(
iter_bytes,
content=(
#|b"hello"
),
)
}

#Converting Between Formats

Bytes can be converted to and from different formats:

///|
test "bytes conversion" {
let original : ReadOnlyArray[Byte] = [b'x', b'y', b'z']
let bytes = Bytes::from_array(original)

// Convert to array
let array = bytes.to_array()
debug_inspect(
array,
content=(
#|[0x78, 0x79, 0x7a]
),
)

// Convert to fixed array
let fixed = bytes.to_fixedarray()
debug_inspect(
fixed,
content=(
#|<FixedArray: [0x78, 0x79, 0x7a]>
),
)

// Convert to iterator and collect back
let collected = bytes.iter().to_array()
debug_inspect(
collected,
content=(
#|[0x78, 0x79, 0x7a]
),
)
}

#Working with Views

Views provide a way to work with portions of bytes and interpret them as various numeric types:

///|
test "bytes view operations" {
// Create bytes with numeric data
let num_bytes = Bytes::from_array([0x12, 0x34, 0x56, 0x78])

// Create a view
let view = num_bytes[:]

// Get individual bytes
inspect(view[0], content="b'\\x12'")

// Interpret as integers (big-endian)
guard view is [i32be(x), ..] else {
fail("Failed to match big-endian integer pattern")
}
inspect(x, content="305419896")

// Interpret as integers (little-endian)
guard view is [i32le(y), ..] else {
fail("Failed to match little-endian integer pattern")
}
inspect(y, content="2018915346")

// Create a sub-view
let sub_view = view[1:3]
inspect(sub_view.length(), content="2")
}

#Binary Data Interpretation

Views provide methods to interpret byte sequences as various numeric types in both little-endian and big-endian formats:

///|
test "numeric interpretation" {
// Create test data
let int64_bytes = Bytes::from_array([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
])
guard int64_bytes is [i64be(x), ..] else {
fail("Failed to match big-endian int64 pattern")
}
inspect(x, content="66")
guard int64_bytes is [u64le(x), ..] else {
fail("Failed to match little-endian uint64 pattern")
}
inspect(x, content="4755801206503243776")
}

#Concatenation and Comparison

Bytes can be concatenated and compared:

///|
test "bytes operations" {
let b1 = Bytes::from_array([b'a', b'b'])
let b2 = Bytes::from_array([b'c', b'd'])

// Concatenation
let combined = b1 + b2
inspect(
combined,
content=(
#|b"abcd"
),
)

// Comparison
let same = Bytes::from_array([b'a', b'b'])
let different = Bytes::from_array([b'x', b'y'])
inspect(b1 == same, content="true")
inspect(b1 == different, content="false")
inspect(b1 < b2, content="true")
}

#Prefixes, Suffixes, and Chopping

You can check for prefixes and suffixes or remove them when present:

///|
test "bytes prefix/suffix" {
let bytes = b"hello"
inspect(bytes.has_prefix(b"he"), content="true")
inspect(bytes.has_suffix(b"lo"), content="true")
debug_inspect(
bytes.chop_prefix(b"he"),
content="Some(<BytesView: [0x6c, 0x6c, 0x6f]>)",
)
debug_inspect(
bytes.chop_suffix(b"lo"),
content="Some(<BytesView: [0x68, 0x65, 0x6c]>)",
)
debug_inspect(bytes.chop_prefix(b"zz"), content="None")
}

#
View

using @moonbitlang/core/builtin { type BytesView as View }

Type View used by this package APIs.

#
BytesRegex

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
type BytesRegex

#
BytesRegex::execute

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn BytesRegex::execute(self : BytesRegex, input : BytesView, last_index? : Int) -> MatchResult?

Execute using this compiled object.

#
MatchResult

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
type MatchResult

#
MatchResult::after

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn MatchResult::after(self : MatchResult) -> BytesView

Return match after view.

#
MatchResult::before

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn MatchResult::before(self : MatchResult) -> BytesView

Return match before view.

#
MatchResult::content

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn MatchResult::content(self : MatchResult) -> BytesView

Return match content view.

#
MatchResult::group

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn MatchResult::group(self : MatchResult, group_index : Int) -> BytesView?

Access capture group information.

#
MatchResult::named_group

#internal(experimental, "subject to breaking change without notice")
#deprecated("Bytes regex APIs are deprecated and will be removed.")
fn MatchResult::named_group(self : MatchResult, name : String) -> BytesView?

Access capture named_group information.