use crate::api::generated::machine::DmesgRequest as ProtoDmesgRequest;
#[derive(Debug, Clone, Default)]
pub struct DmesgRequest {
pub follow: bool,
pub tail: bool,
}
impl DmesgRequest {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn follow() -> Self {
Self {
follow: true,
tail: false,
}
}
#[must_use]
pub fn tail() -> Self {
Self {
follow: false,
tail: true,
}
}
#[must_use]
pub fn builder() -> DmesgRequestBuilder {
DmesgRequestBuilder::default()
}
}
impl From<DmesgRequest> for ProtoDmesgRequest {
fn from(req: DmesgRequest) -> Self {
Self {
follow: req.follow,
tail: req.tail,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct DmesgRequestBuilder {
follow: bool,
tail: bool,
}
impl DmesgRequestBuilder {
#[must_use]
pub fn follow(mut self, follow: bool) -> Self {
self.follow = follow;
self
}
#[must_use]
pub fn tail(mut self, tail: bool) -> Self {
self.tail = tail;
self
}
#[must_use]
pub fn build(self) -> DmesgRequest {
DmesgRequest {
follow: self.follow,
tail: self.tail,
}
}
}
#[derive(Debug, Clone)]
pub struct DmesgResponse {
data: Vec<u8>,
pub node: Option<String>,
}
impl DmesgResponse {
#[must_use]
pub fn new(data: Vec<u8>, node: Option<String>) -> Self {
Self { data, node }
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
pub fn as_str(&self) -> Result<&str, std::str::Utf8Error> {
std::str::from_utf8(&self.data)
}
#[must_use]
pub fn as_string_lossy(&self) -> std::borrow::Cow<'_, str> {
String::from_utf8_lossy(&self.data)
}
#[must_use]
pub fn len(&self) -> usize {
self.data.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
#[must_use]
pub fn lines(&self) -> Vec<&str> {
self.as_str()
.map(|s| s.lines().collect())
.unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dmesg_request_new() {
let req = DmesgRequest::new();
assert!(!req.follow);
assert!(!req.tail);
}
#[test]
fn test_dmesg_request_follow() {
let req = DmesgRequest::follow();
assert!(req.follow);
assert!(!req.tail);
}
#[test]
fn test_dmesg_request_tail() {
let req = DmesgRequest::tail();
assert!(!req.follow);
assert!(req.tail);
}
#[test]
fn test_dmesg_request_builder() {
let req = DmesgRequest::builder().follow(true).tail(true).build();
assert!(req.follow);
assert!(req.tail);
}
#[test]
fn test_proto_conversion() {
let req = DmesgRequest::builder().follow(true).tail(false).build();
let proto: ProtoDmesgRequest = req.into();
assert!(proto.follow);
assert!(!proto.tail);
}
#[test]
fn test_dmesg_response() {
let data = b"[ 0.000000] Linux version 5.15.0\n[ 0.000001] Command line: talos.platform=metal".to_vec();
let response = DmesgResponse::new(data.clone(), Some("node1".to_string()));
assert_eq!(response.len(), data.len());
assert!(!response.is_empty());
assert!(response.as_str().is_ok());
assert_eq!(response.lines().len(), 2);
assert!(response.lines()[0].contains("Linux version"));
}
}