mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: add a new sender property to the DDS payload (#855)
This commit is contained in:
parent
fd455a1ae4
commit
bfcf401b40
12 changed files with 90 additions and 111 deletions
|
|
@ -8,7 +8,7 @@ use crate::Payload;
|
|||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Body<'a> {
|
||||
Hi(BodyHi),
|
||||
Hi(BodyHi<'a>),
|
||||
Hey(BodyHey),
|
||||
Tabs(BodyTabs<'a>),
|
||||
Cd(BodyCd<'a>),
|
||||
|
|
|
|||
|
|
@ -32,12 +32,7 @@ impl<'a> From<BodyBulk<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua<'_> for BodyBulk<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua
|
||||
.create_any_userdata(BodyBulkIter {
|
||||
tab: self.tab,
|
||||
inner: self.changes.into_owned().into_iter(),
|
||||
})?
|
||||
.into_lua(lua)
|
||||
BodyBulkIter { tab: self.tab, inner: self.changes.into_owned().into_iter() }.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,22 +8,23 @@ use super::Body;
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyCd<'a> {
|
||||
pub owned: bool,
|
||||
pub tab: usize,
|
||||
pub url: Cow<'a, Url>,
|
||||
pub tab: usize,
|
||||
pub url: Cow<'a, Url>,
|
||||
#[serde(skip)]
|
||||
dummy: bool,
|
||||
}
|
||||
|
||||
impl<'a> BodyCd<'a> {
|
||||
#[inline]
|
||||
pub fn borrowed(tab: usize, url: &'a Url) -> Body<'a> {
|
||||
Self { owned: false, tab, url: Cow::Borrowed(url) }.into()
|
||||
Self { tab, url: Cow::Borrowed(url), dummy: false }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BodyCd<'static> {
|
||||
#[inline]
|
||||
pub fn owned(tab: usize) -> Body<'static> {
|
||||
Self { owned: false, tab, url: Default::default() }.into()
|
||||
pub fn dummy(tab: usize) -> Body<'static> {
|
||||
Self { tab, url: Default::default(), dummy: true }.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -33,10 +34,10 @@ impl<'a> From<BodyCd<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua<'_> for BodyCd<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
if self.owned {
|
||||
if let Some(Cow::Owned(url)) = Some(self.url).filter(|_| !self.dummy) {
|
||||
lua.create_table_from([
|
||||
("tab", self.tab.into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(self.url.into_owned())?.into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
|
||||
])?
|
||||
} else {
|
||||
lua.create_table_from([("tab", self.tab)])?
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashSet;
|
||||
use std::{borrow::Cow, collections::HashSet};
|
||||
|
||||
use mlua::{ExternalResult, IntoLua, Lua, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -6,16 +6,22 @@ use serde::{Deserialize, Serialize};
|
|||
use super::Body;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyHi {
|
||||
pub id: u64,
|
||||
pub abilities: HashSet<String>,
|
||||
pub struct BodyHi<'a> {
|
||||
pub abilities: HashSet<Cow<'a, String>>,
|
||||
}
|
||||
|
||||
impl From<BodyHi> for Body<'_> {
|
||||
fn from(value: BodyHi) -> Self { Self::Hi(value) }
|
||||
impl<'a> BodyHi<'a> {
|
||||
#[inline]
|
||||
pub fn borrowed(abilities: HashSet<&'a String>) -> Body<'a> {
|
||||
Self { abilities: abilities.into_iter().map(Cow::Borrowed).collect() }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua<'_> for BodyHi {
|
||||
impl<'a> From<BodyHi<'a>> for Body<'a> {
|
||||
fn from(value: BodyHi<'a>) -> Self { Self::Hi(value) }
|
||||
}
|
||||
|
||||
impl IntoLua<'_> for BodyHi<'_> {
|
||||
fn into_lua(self, _: &Lua) -> mlua::Result<Value<'_>> {
|
||||
Err("BodyHi cannot be converted to Lua").into_lua_err()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,21 +8,20 @@ use super::Body;
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyHover<'a> {
|
||||
pub owned: bool,
|
||||
pub tab: usize,
|
||||
pub url: Option<Cow<'a, Url>>,
|
||||
pub tab: usize,
|
||||
pub url: Option<Cow<'a, Url>>,
|
||||
}
|
||||
|
||||
impl<'a> BodyHover<'a> {
|
||||
#[inline]
|
||||
pub fn borrowed(tab: usize, url: Option<&'a Url>) -> Body<'a> {
|
||||
Self { owned: false, tab, url: url.map(Cow::Borrowed) }.into()
|
||||
Self { tab, url: url.map(Cow::Borrowed) }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BodyHover<'static> {
|
||||
#[inline]
|
||||
pub fn owned(tab: usize) -> Body<'static> { Self { owned: false, tab, url: None }.into() }
|
||||
pub fn dummy(tab: usize) -> Body<'static> { Self { tab, url: None }.into() }
|
||||
}
|
||||
|
||||
impl<'a> From<BodyHover<'a>> for Body<'a> {
|
||||
|
|
@ -31,10 +30,10 @@ impl<'a> From<BodyHover<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua<'_> for BodyHover<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
if self.owned && self.url.is_some() {
|
||||
if let Some(Cow::Owned(url)) = self.url {
|
||||
lua.create_table_from([
|
||||
("tab", self.tab.into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(self.url.unwrap().into_owned())?.into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
|
||||
])?
|
||||
} else {
|
||||
lua.create_table_from([("tab", self.tab)])?
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl<'a> BodyRename<'a> {
|
|||
|
||||
impl BodyRename<'static> {
|
||||
#[inline]
|
||||
pub fn owned(tab: usize, from: &Url, to: &Url) -> Body<'static> {
|
||||
pub fn dummy(tab: usize, from: &Url, to: &Url) -> Body<'static> {
|
||||
Self { tab, from: Cow::Owned(from.clone()), to: Cow::Owned(to.clone()) }.into()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use mlua::{IntoLua, Lua, MetaMethod, UserData, Value};
|
||||
use mlua::{MetaMethod, UserData};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_shared::fs::Url;
|
||||
|
||||
|
|
@ -8,7 +8,6 @@ use super::Body;
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyTabs<'a> {
|
||||
pub owned: bool,
|
||||
pub cursor: usize,
|
||||
pub items: Vec<BodyTabsItem<'a>>,
|
||||
}
|
||||
|
|
@ -16,59 +15,20 @@ pub struct BodyTabs<'a> {
|
|||
impl<'a> BodyTabs<'a> {
|
||||
#[inline]
|
||||
pub fn borrowed(cursor: usize, urls: &[&'a Url]) -> Body<'a> {
|
||||
Self {
|
||||
owned: false,
|
||||
cursor,
|
||||
items: urls.iter().map(|&u| BodyTabsItem { url: Cow::Borrowed(u) }).collect(),
|
||||
}
|
||||
.into()
|
||||
Self { cursor, items: urls.iter().map(|&u| BodyTabsItem::from(u)).collect() }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BodyTabs<'static> {
|
||||
#[inline]
|
||||
pub fn owned(cursor: usize) -> Body<'static> {
|
||||
Self { owned: false, cursor, items: Default::default() }.into()
|
||||
}
|
||||
pub fn dummy(cursor: usize) -> Body<'static> { Self { cursor, items: Default::default() }.into() }
|
||||
}
|
||||
|
||||
impl<'a> From<BodyTabs<'a>> for Body<'a> {
|
||||
fn from(value: BodyTabs<'a>) -> Self { Self::Tabs(value) }
|
||||
}
|
||||
|
||||
impl IntoLua<'_> for BodyTabs<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value<'_>> {
|
||||
if self.owned {
|
||||
BodyTabsIter::from(self).into_lua(lua)
|
||||
} else {
|
||||
lua.create_table_from([("cursor", self.cursor)])?.into_lua(lua)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Item
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct BodyTabsItem<'a> {
|
||||
pub url: Cow<'a, Url>,
|
||||
}
|
||||
|
||||
impl UserData for BodyTabsItem<'static> {
|
||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("url", |lua, me| lua.create_any_userdata(me.url.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Iterator
|
||||
pub struct BodyTabsIter {
|
||||
pub cursor: usize,
|
||||
pub items: Vec<BodyTabsItem<'static>>,
|
||||
}
|
||||
|
||||
impl From<BodyTabs<'static>> for BodyTabsIter {
|
||||
fn from(value: BodyTabs<'static>) -> Self { Self { cursor: value.cursor, items: value.items } }
|
||||
}
|
||||
|
||||
impl UserData for BodyTabsIter {
|
||||
impl UserData for BodyTabs<'static> {
|
||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
|
||||
}
|
||||
|
|
@ -81,3 +41,19 @@ impl UserData for BodyTabsIter {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- Item
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct BodyTabsItem<'a> {
|
||||
pub url: Cow<'a, Url>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Url> for BodyTabsItem<'a> {
|
||||
fn from(value: &'a Url) -> Self { Self { url: Cow::Borrowed(value) } }
|
||||
}
|
||||
|
||||
impl UserData for BodyTabsItem<'static> {
|
||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("url", |lua, me| lua.create_any_userdata(me.url.clone()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,23 +8,20 @@ use super::Body;
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyYank<'a> {
|
||||
pub owned: bool,
|
||||
pub cut: bool,
|
||||
pub urls: Cow<'a, HashSet<Url>>,
|
||||
pub cut: bool,
|
||||
pub urls: Cow<'a, HashSet<Url>>,
|
||||
}
|
||||
|
||||
impl<'a> BodyYank<'a> {
|
||||
#[inline]
|
||||
pub fn borrowed(cut: bool, urls: &'a HashSet<Url>) -> Body<'a> {
|
||||
Self { owned: false, cut, urls: Cow::Borrowed(urls) }.into()
|
||||
Self { cut, urls: Cow::Borrowed(urls) }.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BodyYank<'static> {
|
||||
#[inline]
|
||||
pub fn owned(cut: bool) -> Body<'static> {
|
||||
Self { owned: false, cut, urls: Default::default() }.into()
|
||||
}
|
||||
pub fn dummy(cut: bool) -> Body<'static> { Self { cut, urls: Default::default() }.into() }
|
||||
}
|
||||
|
||||
impl<'a> From<BodyYank<'a>> for Body<'a> {
|
||||
|
|
@ -33,8 +30,8 @@ impl<'a> From<BodyYank<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua<'_> for BodyYank<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value<'_>> {
|
||||
if self.owned {
|
||||
BodyYankIter::from(self).into_lua(lua)
|
||||
if let Cow::Owned(urls) = self.urls {
|
||||
BodyYankIter { cut: self.cut, urls: urls.into_iter().collect() }.into_lua(lua)
|
||||
} else {
|
||||
lua.create_table_from([("cut", self.cut)])?.into_lua(lua)
|
||||
}
|
||||
|
|
@ -47,12 +44,6 @@ pub struct BodyYankIter {
|
|||
pub urls: Vec<Url>,
|
||||
}
|
||||
|
||||
impl From<BodyYank<'static>> for BodyYankIter {
|
||||
fn from(value: BodyYank) -> Self {
|
||||
Self { cut: value.cut, urls: value.urls.into_owned().into_iter().collect() }
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for BodyYankIter {
|
||||
fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("is_cut", |_, me| Ok(me.cut));
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@ use anyhow::{anyhow, Result};
|
|||
use yazi_boot::BOOT;
|
||||
use yazi_shared::{emit, event::Cmd, Layer};
|
||||
|
||||
use crate::body::Body;
|
||||
use crate::{body::Body, ID};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Payload<'a> {
|
||||
pub receiver: u64,
|
||||
pub severity: u8,
|
||||
pub sender: u64,
|
||||
pub body: Body<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Payload<'a> {
|
||||
#[inline]
|
||||
pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, severity: 0, body } }
|
||||
pub(super) fn new(body: Body<'a>) -> Self { Self { receiver: 0, severity: 0, sender: *ID, body } }
|
||||
|
||||
#[inline]
|
||||
pub(super) fn with_receiver(mut self, receiver: u64) -> Self {
|
||||
|
|
@ -56,7 +57,7 @@ impl FromStr for Payload<'_> {
|
|||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.splitn(4, ',');
|
||||
let mut parts = s.splitn(5, ',');
|
||||
|
||||
let kind = parts.next().ok_or_else(|| anyhow!("empty kind"))?;
|
||||
|
||||
|
|
@ -66,9 +67,12 @@ impl FromStr for Payload<'_> {
|
|||
let severity =
|
||||
parts.next().and_then(|s| s.parse().ok()).ok_or_else(|| anyhow!("invalid severity"))?;
|
||||
|
||||
let sender =
|
||||
parts.next().and_then(|s| s.parse().ok()).ok_or_else(|| anyhow!("invalid sender"))?;
|
||||
|
||||
let body = parts.next().ok_or_else(|| anyhow!("empty body"))?;
|
||||
|
||||
Ok(Self { receiver, severity, body: Body::from_str(kind, body)? })
|
||||
Ok(Self { receiver, severity, sender, body: Body::from_str(kind, body)? })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +91,7 @@ impl Display for Payload<'_> {
|
|||
};
|
||||
|
||||
if let Ok(s) = result {
|
||||
write!(f, "{},{},{},{s}", self.body.kind(), self.receiver, self.severity)
|
||||
write!(f, "{},{},{},{},{s}", self.body.kind(), self.receiver, self.severity, self.sender)
|
||||
} else {
|
||||
Err(std::fmt::Error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,69 +88,70 @@ impl Pubsub {
|
|||
}
|
||||
|
||||
pub fn pub_from_hi() -> bool {
|
||||
Client::push(Payload::new(
|
||||
BodyHi { id: *ID, abilities: REMOTE.read().keys().cloned().collect() }.into(),
|
||||
));
|
||||
let abilities = REMOTE.read().keys().cloned().collect();
|
||||
let abilities = BOOT.remote_events.union(&abilities).collect();
|
||||
|
||||
Client::push(BodyHi::borrowed(abilities).upgrade());
|
||||
true
|
||||
}
|
||||
|
||||
pub fn pub_from_tabs(tab: usize, urls: &[&Url]) {
|
||||
if LOCAL.read().contains_key("tabs") {
|
||||
Self::pub_(BodyTabs::owned(tab));
|
||||
Self::pub_(BodyTabs::dummy(tab));
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("tabs")) {
|
||||
Client::push(BodyTabs::borrowed(tab, urls).upgrade());
|
||||
}
|
||||
if BOOT.local_events.contains("tabs") {
|
||||
BodyTabs::borrowed(tab, urls).upgrade().flush(true);
|
||||
BodyTabs::borrowed(tab, urls).upgrade().with_receiver(*ID).flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pub_from_cd(tab: usize, url: &Url) {
|
||||
if LOCAL.read().contains_key("cd") {
|
||||
Self::pub_(BodyCd::owned(tab));
|
||||
Self::pub_(BodyCd::dummy(tab));
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("cd")) {
|
||||
Client::push(BodyCd::borrowed(tab, url).upgrade());
|
||||
}
|
||||
if BOOT.local_events.contains("cd") {
|
||||
BodyCd::borrowed(tab, url).upgrade().flush(true);
|
||||
BodyCd::borrowed(tab, url).upgrade().with_receiver(*ID).flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pub_from_hover(tab: usize, url: Option<&Url>) {
|
||||
if LOCAL.read().contains_key("hover") {
|
||||
Self::pub_(BodyHover::owned(tab));
|
||||
Self::pub_(BodyHover::dummy(tab));
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("hover")) {
|
||||
Client::push(BodyHover::borrowed(tab, url).upgrade());
|
||||
}
|
||||
if BOOT.local_events.contains("hover") {
|
||||
BodyHover::borrowed(tab, url).upgrade().flush(true);
|
||||
BodyHover::borrowed(tab, url).upgrade().with_receiver(*ID).flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pub_from_rename(tab: usize, from: &Url, to: &Url) {
|
||||
if LOCAL.read().contains_key("rename") {
|
||||
Self::pub_(BodyRename::owned(tab, from, to));
|
||||
Self::pub_(BodyRename::dummy(tab, from, to));
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("rename")) {
|
||||
Client::push(BodyRename::borrowed(tab, from, to).upgrade());
|
||||
}
|
||||
if BOOT.local_events.contains("rename") {
|
||||
BodyRename::borrowed(tab, from, to).upgrade().flush(true);
|
||||
BodyRename::borrowed(tab, from, to).upgrade().with_receiver(*ID).flush(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pub_from_yank(cut: bool, urls: &HashSet<Url>) {
|
||||
if LOCAL.read().contains_key("yank") {
|
||||
Self::pub_(BodyYank::owned(cut));
|
||||
Self::pub_(BodyYank::dummy(cut));
|
||||
}
|
||||
if PEERS.read().values().any(|p| p.able("yank")) {
|
||||
Client::push(BodyYank::borrowed(cut, urls).upgrade());
|
||||
}
|
||||
if BOOT.local_events.contains("yank") {
|
||||
BodyYank::borrowed(cut, urls).upgrade().flush(true);
|
||||
BodyYank::borrowed(cut, urls).upgrade().with_receiver(*ID).flush(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,16 +92,21 @@ impl Server {
|
|||
}
|
||||
|
||||
fn handle_hi(s: String, id: &mut Option<u64>, tx: mpsc::UnboundedSender<String>) {
|
||||
let Ok(Body::Hi(hi)) = Payload::from_str(&s).map(|p| p.body) else { return };
|
||||
let Ok(payload) = Payload::from_str(&s) else { return };
|
||||
let Body::Hi(hi) = payload.body else { return };
|
||||
|
||||
let mut clients = CLIENTS.write();
|
||||
id.replace(hi.id).and_then(|id| clients.remove(&id));
|
||||
id.replace(payload.sender).and_then(|id| clients.remove(&id));
|
||||
|
||||
if let Some(ref state) = *STATE.read() {
|
||||
state.values().for_each(|s| _ = tx.send(format!("{s}\n")));
|
||||
}
|
||||
|
||||
clients.insert(hi.id, Client { id: hi.id, tx, abilities: hi.abilities });
|
||||
clients.insert(payload.sender, Client {
|
||||
id: payload.sender,
|
||||
tx,
|
||||
abilities: hi.abilities.into_iter().map(|s| s.into_owned()).collect(),
|
||||
});
|
||||
Self::handle_hey(&clients);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,11 @@ impl State {
|
|||
|
||||
let mut inner = HashMap::new();
|
||||
while buf.read_line(&mut line).await? > 0 {
|
||||
let mut parts = line.splitn(4, ',');
|
||||
let mut parts = line.splitn(5, ',');
|
||||
let Some(kind) = parts.next() else { continue };
|
||||
let Some(_) = parts.next() else { continue };
|
||||
let Some(severity) = parts.next().and_then(|s| s.parse::<u8>().ok()) else { continue };
|
||||
let Some(_) = parts.next() else { continue };
|
||||
let Some(body) = parts.next() else { continue };
|
||||
inner.insert(format!("{}_{severity}_{kind}", Body::tab(kind, body)), mem::take(&mut line));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue