Skip to main content

sim_lib_midi_core/
meta_view.rs

1//! Typed views over raw [`MetaBucket`] payloads.
2//!
3//! These helpers interpret the common Standard MIDI File meta types (text,
4//! track name, marker, SMPTE offset) and build the matching buckets, without
5//! the core model needing a variant per meta type.
6
7use crate::{MetaBucket, SmpteOffset};
8
9/// Returns the bucket's UTF-8 text if it is a text meta event (type `0x01`).
10pub fn as_text(bucket: &MetaBucket) -> Option<&str> {
11    (bucket.type_byte == 0x01)
12        .then(|| std::str::from_utf8(&bucket.data).ok())
13        .flatten()
14}
15
16/// Returns the bucket's UTF-8 text if it is a track-name meta event (type
17/// `0x03`).
18pub fn as_track_name(bucket: &MetaBucket) -> Option<&str> {
19    (bucket.type_byte == 0x03)
20        .then(|| std::str::from_utf8(&bucket.data).ok())
21        .flatten()
22}
23
24/// Returns the bucket's UTF-8 text if it is a marker meta event (type `0x06`).
25pub fn as_marker(bucket: &MetaBucket) -> Option<&str> {
26    (bucket.type_byte == 0x06)
27        .then(|| std::str::from_utf8(&bucket.data).ok())
28        .flatten()
29}
30
31/// Returns the [`SmpteOffset`] if the bucket is a 5-byte SMPTE-offset meta
32/// event (type `0x54`).
33pub fn as_smpte_offset(bucket: &MetaBucket) -> Option<SmpteOffset> {
34    (bucket.type_byte == 0x54 && bucket.data.len() == 5).then(|| SmpteOffset {
35        hours: bucket.data[0],
36        minutes: bucket.data[1],
37        seconds: bucket.data[2],
38        frames: bucket.data[3],
39        subframes: bucket.data[4],
40    })
41}
42
43/// Builds a text meta bucket (type `0x01`) from `value`.
44pub fn make_text(value: &str) -> MetaBucket {
45    MetaBucket {
46        type_byte: 0x01,
47        data: value.as_bytes().to_vec(),
48    }
49}
50
51/// Builds a track-name meta bucket (type `0x03`) from `value`.
52pub fn make_track_name(value: &str) -> MetaBucket {
53    MetaBucket {
54        type_byte: 0x03,
55        data: value.as_bytes().to_vec(),
56    }
57}
58
59/// Builds a marker meta bucket (type `0x06`) from `value`.
60pub fn make_marker(value: &str) -> MetaBucket {
61    MetaBucket {
62        type_byte: 0x06,
63        data: value.as_bytes().to_vec(),
64    }
65}
66
67/// Builds a SMPTE-offset meta bucket (type `0x54`) from `offset`.
68pub fn make_smpte_offset(offset: SmpteOffset) -> MetaBucket {
69    MetaBucket {
70        type_byte: 0x54,
71        data: vec![
72            offset.hours,
73            offset.minutes,
74            offset.seconds,
75            offset.frames,
76            offset.subframes,
77        ],
78    }
79}