yazi_scheduler/plugin/
plugin.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use anyhow::{Result, anyhow};
use tokio::sync::mpsc;
use yazi_plugin::isolate;

use super::{PluginOp, PluginOpEntry};
use crate::{HIGH, TaskOp, TaskProg};

pub struct Plugin {
	macro_: async_priority_channel::Sender<TaskOp, u8>,
	prog:   mpsc::UnboundedSender<TaskProg>,
}

impl Plugin {
	pub fn new(
		macro_: async_priority_channel::Sender<TaskOp, u8>,
		prog: mpsc::UnboundedSender<TaskProg>,
	) -> Self {
		Self { macro_, prog }
	}

	pub async fn work(&self, op: PluginOp) -> Result<()> {
		match op {
			PluginOp::Entry(task) => {
				isolate::entry(task.opt).await?;
			}
		}
		Ok(())
	}

	pub async fn micro(&self, task: PluginOpEntry) -> Result<()> {
		self.prog.send(TaskProg::New(task.id, 0))?;

		if let Err(e) = isolate::entry(task.opt).await {
			self.fail(task.id, format!("Failed to run the plugin:\n{e}"))?;
			return Ok(());
		}

		self.prog.send(TaskProg::Adv(task.id, 1, 0))?;
		self.succ(task.id)
	}

	pub fn macro_(&self, task: PluginOpEntry) -> Result<()> {
		let id = task.id;

		self.prog.send(TaskProg::New(id, 0))?;
		self.queue(PluginOp::Entry(task), HIGH)?;
		self.succ(id)
	}
}

impl Plugin {
	#[inline]
	fn succ(&self, id: usize) -> Result<()> { Ok(self.prog.send(TaskProg::Succ(id))?) }

	#[inline]
	fn fail(&self, id: usize, reason: String) -> Result<()> {
		Ok(self.prog.send(TaskProg::Fail(id, reason))?)
	}

	#[inline]
	fn queue(&self, op: impl Into<TaskOp>, priority: u8) -> Result<()> {
		self.macro_.try_send(op.into(), priority).map_err(|_| anyhow!("Failed to send task"))
	}
}