yazi/yazi-dds/src/payload.rs
2024-03-29 23:30:30 +08:00

95 lines
2.3 KiB
Rust

use std::{fmt::Display, io::Write, str::FromStr};
use anyhow::{anyhow, Result};
use yazi_boot::BOOT;
use yazi_shared::{emit, event::Cmd, Layer};
use crate::body::Body;
#[derive(Debug)]
pub struct Payload<'a> {
pub receiver: u64,
pub severity: u8,
pub body: Body<'a>,
}
impl<'a> Payload<'a> {
#[inline]
pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, severity: 0, body } }
#[inline]
pub(super) fn with_receiver(mut self, receiver: u64) -> Self {
self.receiver = receiver;
self
}
#[inline]
pub(super) fn with_severity(mut self, severity: u8) -> Self {
self.severity = severity;
self
}
pub(super) fn flush(self, force: bool) -> Self {
let b = force
|| if self.receiver == 0 {
BOOT.remote_events.contains(self.body.kind())
} else if let Body::Custom(b) = &self.body {
BOOT.local_events.contains(&b.kind)
} else {
false
};
if b {
writeln!(std::io::stdout(), "{self}").ok();
}
self
}
}
impl Payload<'static> {
pub(super) fn emit(self) {
emit!(Call(Cmd::new("accept_payload").with_data(self), Layer::App));
}
}
impl FromStr for Payload<'_> {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.splitn(4, ',');
let kind = parts.next().ok_or_else(|| anyhow!("empty kind"))?;
let receiver =
parts.next().and_then(|s| s.parse().ok()).ok_or_else(|| anyhow!("invalid receiver"))?;
let severity =
parts.next().and_then(|s| s.parse().ok()).ok_or_else(|| anyhow!("invalid severity"))?;
let body = parts.next().ok_or_else(|| anyhow!("empty body"))?;
Ok(Self { receiver, severity, body: Body::from_str(kind, body)? })
}
}
impl Display for Payload<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let result = match &self.body {
Body::Hi(b) => serde_json::to_string(b),
Body::Hey(b) => serde_json::to_string(b),
Body::Tabs(b) => serde_json::to_string(b),
Body::Cd(b) => serde_json::to_string(b),
Body::Hover(b) => serde_json::to_string(b),
Body::Rename(b) => serde_json::to_string(b),
Body::Bulk(b) => serde_json::to_string(b),
Body::Yank(b) => serde_json::to_string(b),
Body::Custom(b) => serde_json::to_string(b),
};
if let Ok(s) = result {
write!(f, "{},{},{},{s}", self.body.kind(), self.receiver, self.severity)
} else {
Err(std::fmt::Error)
}
}
}