microfetch_lib/
release.rs

1use std::{fmt::Write as _, io};
2
3use crate::{UtsName, syscall::read_file_fast};
4
5#[must_use]
6#[cfg_attr(feature = "hotpath", hotpath::measure)]
7pub fn get_system_info(utsname: &UtsName) -> String {
8  let sysname = utsname.sysname().to_str().unwrap_or("Unknown");
9  let release = utsname.release().to_str().unwrap_or("Unknown");
10  let machine = utsname.machine().to_str().unwrap_or("Unknown");
11
12  // Pre-allocate capacity: sysname + " " + release + " (" + machine + ")"
13  let capacity = sysname.len() + 1 + release.len() + 2 + machine.len() + 1;
14  let mut result = String::with_capacity(capacity);
15
16  write!(result, "{sysname} {release} ({machine})").unwrap();
17  result
18}
19
20/// Gets the pretty name of the OS from `/etc/os-release`.
21///
22/// # Errors
23///
24/// Returns an error if `/etc/os-release` cannot be read.
25#[cfg_attr(feature = "hotpath", hotpath::measure)]
26pub fn get_os_pretty_name() -> Result<String, io::Error> {
27  // Fast byte-level scanning for PRETTY_NAME=
28  const PREFIX: &[u8] = b"PRETTY_NAME=";
29
30  let mut buffer = [0u8; 1024];
31
32  // Use fast syscall-based file reading
33  let bytes_read = read_file_fast("/etc/os-release", &mut buffer)?;
34  let content = &buffer[..bytes_read];
35
36  let mut offset = 0;
37
38  while offset < content.len() {
39    let remaining = &content[offset..];
40
41    // Find newline or end
42    let line_end = remaining
43      .iter()
44      .position(|&b| b == b'\n')
45      .unwrap_or(remaining.len());
46    let line = &remaining[..line_end];
47
48    if line.starts_with(PREFIX) {
49      let value = &line[PREFIX.len()..];
50
51      // Strip quotes if present
52      let trimmed = if value.len() >= 2
53        && value[0] == b'"'
54        && value[value.len() - 1] == b'"'
55      {
56        &value[1..value.len() - 1]
57      } else {
58        value
59      };
60
61      // Convert to String - should be valid UTF-8
62      return Ok(String::from_utf8_lossy(trimmed).into_owned());
63    }
64
65    offset += line_end + 1;
66  }
67
68  Ok("Unknown".to_owned())
69}