pub struct Version {
pub major: i32,
pub minor: i32,
pub bugfix: i32,
}Expand description
A Bela version: major, minor and bugfix.
Ordered the way version numbers are — major first, then minor, then bugfix — so a program can ask whether the library it found is new enough for what it is about to use:
use bela::Version;
assert!(Version::new(1, 18, 0) >= Version::new(1, 17, 0));
assert_eq!(Version::new(1, 18, 0).to_string(), "1.18.0");The three numbers are C ints in the API that fills them, and they
are kept as they arrived: deciding what a negative version number
means is not this crate’s to do, and a saturated one would be a
number nobody reported.
§Why the fields are public
Because there is nothing to keep them consistent with. Every
combination of three ints is a version this type is willing to
hold — that is the paragraph above — and new
already builds any of them, so private fields would add three
getters without narrowing what can exist.
Board and DetectMode are closed differently, and for a
reason that does not reach here: they are C enums whose set of
values moves with the board image, so they are #[non_exhaustive]
and Board::Unrecognised is unforgeable — a hand-built one could
carry a number a named variant already has and then compare unequal
to it. A version has no such variant to contradict, and its shape
is fixed by Bela_getVersion, which fills in exactly three
numbers.
Fields§
§major: i32The major version.
minor: i32The minor version.
bugfix: i32The bugfix version.
Implementations§
Source§impl Version
impl Version
Sourcepub const HEADERS: Self
pub const HEADERS: Self
What the headers this crate was built against said.
BELA_MAJOR_VERSION and its siblings, as vendored in
bela-sys. Compared with running it says
whether the board’s image is the one the bindings describe;
they differ when a binary is run on a board other than the one
its sysroot came from.
Sourcepub const fn new(major: i32, minor: i32, bugfix: i32) -> Self
pub const fn new(major: i32, minor: i32, bugfix: i32) -> Self
A version from its three numbers.
Sourcepub fn running() -> Self
pub fn running() -> Self
Asks the libbela this program is linked against which version
it is.
The library’s own answer, not the headers’: a binary built against one image and run on another reports the version it found there. No audio system is involved.
Only available on the device target
(aarch64-unknown-linux-gnu).
Examples found in repository?
38fn main() -> ExitCode {
39 use core::iter::once;
40 use std::env::args;
41
42 use bela::{Board, DetectMode, Version};
43
44 let arguments: Vec<String> = args().skip(1).collect();
45 let all_modes = match arguments.as_slice() {
46 [] => false,
47 [flag] if flag == "--all-modes" => true,
48 _ => {
49 eprintln!(
50 "usage: board_info [--all-modes]\n\
51 \x20 --all-modes ask every detect mode, including the scan that writes\n\
52 \x20 /run/bela/belaconfig"
53 );
54 return ExitCode::FAILURE;
55 }
56 };
57
58 if all_modes {
59 // Named per line, because the interesting result is the one
60 // that disagrees with the others.
61 //
62 // `Scan` goes last however `DetectMode::ALL` is ordered: it
63 // writes `/run/bela/belaconfig`, which `Cache`, `CacheOnly` and
64 // `User` read. Asking it first would leave those three
65 // reporting what this same run had just written, and four
66 // modes agreeing would say nothing about the board. Last, they
67 // report what was already on the board and the scan is a fresh
68 // answer to compare with it.
69 let scan_last = DetectMode::ALL
70 .iter()
71 .filter(|mode| **mode != DetectMode::Scan)
72 .chain(once(&DetectMode::Scan));
73 for mode in scan_last {
74 println!("board[{mode}]: {}", Board::detect(*mode));
75 }
76 } else {
77 // `Cache` rather than `Scan`: on a running board the daemon has
78 // already written the file, so this is a file read. It is not
79 // free of side effects — with no file to read it falls back to
80 // scanning, which writes one — but it is the mode that leaves
81 // a working board alone, and `CacheOnly` would answer `NoHw`
82 // on a board that simply had not been scanned yet.
83 println!("board: {}", Board::detect(DetectMode::Cache));
84 }
85
86 // Both versions on one line. They agree on a board whose image is
87 // the one the bindings were vendored from, and the whole point of
88 // printing them together is the run where they do not.
89 let running = Version::running();
90 if running == Version::HEADERS {
91 println!("version: {running}");
92 } else {
93 println!(
94 "version: {running} (this binary was built against {headers})",
95 headers = Version::HEADERS
96 );
97 }
98
99 ExitCode::SUCCESS
100}More examples
250 pub(crate) fn hardware() {
251 let board = Board::detect(DETECT_CACHED);
252 report("detect-hw", &hardware_name(board));
253 // The library that answered, which is not necessarily the one
254 // this was built against: every number below is a claim about a
255 // particular libbela, and this is which one.
256 report("version", &Version::running().to_string());
257 let hw = board.to_sys();
258
259 // The configuration libbela associates with that hardware,
260 // which is where a Gem's channel counts come from before any
261 // settings are applied. Null is an answer too: it is what a
262 // hardware libbela has no configuration for looks like.
263 let config = unsafe { Bela_HwConfig_new(hw) };
264 if config.is_null() {
265 report("hw-config", "null");
266 } else {
267 let config_ref = unsafe { &*config };
268 report(
269 "hw-config",
270 &format!(
271 "rate:{},audio-in:{},audio-out:{},analog-in:{},analog-out:{},digital:{}",
272 config_ref.audioSampleRate,
273 config_ref.audioInChannels,
274 config_ref.audioOutChannels,
275 config_ref.analogInChannels,
276 config_ref.analogOutChannels,
277 config_ref.digitalChannels
278 ),
279 );
280 unsafe { Bela_HwConfig_delete(config) };
281 }
282
283 // The defaults an application inherits by setting nothing,
284 // which is what `Settings`'s "unset fields keep the values
285 // produced by `Bela_defaultSettings()`" means in practice.
286 let raw = unsafe { Bela_InitSettings_alloc() };
287 if raw.is_null() {
288 report("defaults", "alloc-failed");
289 return;
290 }
291 unsafe { Bela_defaultSettings(raw) };
292 let defaults = unsafe { &*raw };
293 report(
294 "defaults-analog",
295 &format!(
296 "use:{},in:{},out:{},uniform:{}",
297 defaults.useAnalog,
298 defaults.numAnalogInChannels,
299 defaults.numAnalogOutChannels,
300 defaults.uniformSampleRate
301 ),
302 );
303 report(
304 "defaults-digital",
305 &format!(
306 "use:{},channels:{}",
307 defaults.useDigital, defaults.numDigitalChannels
308 ),
309 );
310 report(
311 "defaults-audio",
312 &format!(
313 "period:{},rate:{},threads:{}",
314 defaults.periodSize, defaults.audioSampleRate, defaults.threadCount
315 ),
316 );
317 unsafe { Bela_InitSettings_free(raw) };
318 }