forked from 1b-agent/opencadstudio-upstream
style: apply cargo fmt across workspace
This commit is contained in:
1 parent
85710e5454
commit
9cf9ff2c5c
531 files changed
+57740
-33906
No files matched your search
@@ -16,8 +16,8 @@ use interprocess::local_socket::{GenericNamespaced, Stream, ToNsName};
|
||||
use interprocess::TryClone;
|
||||
|
||||
use crate::host::{
|
||||
DocumentReader, ExecutionResult, HostApi, HostNotification, InteractiveCommand,
|
||||
PluginNotification, PluginRequestSender, PluginRequestError, ReaderEntity, HostSettingValue,
|
||||
DocumentReader, ExecutionResult, HostApi, HostNotification, HostSettingValue,
|
||||
InteractiveCommand, PluginNotification, PluginRequestError, PluginRequestSender, ReaderEntity,
|
||||
};
|
||||
use crate::ipc::protocol::{
|
||||
HostRequest, HostResponse, PluginRequest, PluginResponse, RunnerHandshake,
|
||||
@@ -26,7 +26,7 @@ use crate::ipc::transport::{recv, send, TransportError};
|
||||
use crate::ipc::v4::protocol::{
|
||||
HostToPluginV4, NotificationEnvelope, PluginToHostV4, V4_PROTOCOL_VERSION,
|
||||
};
|
||||
use crate::shm::{DocumentViewInfo, SharedDocumentReader, DocumentViewData};
|
||||
use crate::shm::{DocumentViewData, DocumentViewInfo, SharedDocumentReader};
|
||||
|
||||
/// Default capacity of the bounded host→plugin notification queue.
|
||||
const DEFAULT_NOTIFY_QUEUE_SIZE: usize = 1024;
|
||||
@@ -89,8 +89,7 @@ impl V4Client {
|
||||
)))
|
||||
})?;
|
||||
|
||||
let (notify_tx, notify_rx) =
|
||||
mpsc::sync_channel(notify_queue_size());
|
||||
let (notify_tx, notify_rx) = mpsc::sync_channel(notify_queue_size());
|
||||
let (runner_tx, runner_rx) = mpsc::channel();
|
||||
|
||||
let shared = Arc::new(Shared {
|
||||
@@ -101,14 +100,7 @@ impl V4Client {
|
||||
|
||||
let shared_for_reader = Arc::clone(&shared);
|
||||
let notifications = Arc::new(Mutex::new(notify_rx));
|
||||
std::thread::spawn(move || {
|
||||
reader_thread(
|
||||
reader,
|
||||
shared_for_reader,
|
||||
notify_tx,
|
||||
runner_tx,
|
||||
)
|
||||
});
|
||||
std::thread::spawn(move || reader_thread(reader, shared_for_reader, notify_tx, runner_tx));
|
||||
|
||||
Ok(Self {
|
||||
shared,
|
||||
@@ -133,7 +125,11 @@ impl V4Client {
|
||||
|
||||
/// Non-blocking poll for host-to-plugin notifications.
|
||||
pub fn try_recv_notification(&self) -> Option<(Option<u64>, HostNotification)> {
|
||||
self.notifications.lock().unwrap_or_else(|e| e.into_inner()).try_recv().ok()
|
||||
self.notifications
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.try_recv()
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Send a plugin response for a host request.
|
||||
@@ -143,18 +139,11 @@ impl V4Client {
|
||||
resp: HostResponse,
|
||||
) -> Result<(), crate::ipc::transport::TransportError> {
|
||||
let mut writer = self.shared.writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
send(
|
||||
&mut writer,
|
||||
&PluginToHostV4::Response { id, payload: resp },
|
||||
)
|
||||
send(&mut writer, &PluginToHostV4::Response { id, payload: resp })
|
||||
}
|
||||
|
||||
/// Send a plugin-to-host notification.
|
||||
pub fn notify_plugin(
|
||||
&self,
|
||||
command_id: Option<u64>,
|
||||
notification: PluginNotification,
|
||||
) {
|
||||
pub fn notify_plugin(&self, command_id: Option<u64>, notification: PluginNotification) {
|
||||
let envelope = NotificationEnvelope {
|
||||
command_id,
|
||||
payload: notification,
|
||||
@@ -168,10 +157,7 @@ impl V4Client {
|
||||
/// Build a callback that sends a delayed `CodeExecutionResult` response for
|
||||
/// the given request id. Used by `start_execute_code` implementations that
|
||||
/// run REPL code on a background thread.
|
||||
pub fn execute_code_responder(
|
||||
&self,
|
||||
id: u64,
|
||||
) -> Box<dyn FnOnce(ExecutionResult) + Send> {
|
||||
pub fn execute_code_responder(&self, id: u64) -> Box<dyn FnOnce(ExecutionResult) + Send> {
|
||||
let shared = Arc::clone(&self.shared);
|
||||
Box::new(move |result| {
|
||||
let mut writer = shared.writer.lock().unwrap_or_else(|e| e.into_inner());
|
||||
@@ -235,7 +221,10 @@ fn reader_thread(
|
||||
}
|
||||
}
|
||||
Ok(HostToPluginV4::Notification(envelope)) => {
|
||||
if notify_tx.try_send((envelope.command_id, envelope.payload)).is_err() {
|
||||
if notify_tx
|
||||
.try_send((envelope.command_id, envelope.payload))
|
||||
.is_err()
|
||||
{
|
||||
let now = Instant::now();
|
||||
let should_log = last_drop_log
|
||||
.map(|t| now.duration_since(t) >= DROP_LOG_INTERVAL)
|
||||
@@ -247,7 +236,10 @@ fn reader_thread(
|
||||
}
|
||||
}
|
||||
Ok(HostToPluginV4::Request { id, payload }) => {
|
||||
if runner_tx.send(RunnerFrame::Request { id, payload }).is_err() {
|
||||
if runner_tx
|
||||
.send(RunnerFrame::Request { id, payload })
|
||||
.is_err()
|
||||
{
|
||||
// Runner loop has exited; stop reading.
|
||||
break;
|
||||
}
|
||||
@@ -510,9 +502,7 @@ impl HostApi for V4PluginHostApi {
|
||||
|
||||
fn write_record(&mut self, handle: Handle, record: ExtendedDataRecord) -> bool {
|
||||
let app = record.application_name.clone();
|
||||
match self
|
||||
.request(PluginRequest::WriteRecord { handle, record })
|
||||
{
|
||||
match self.request(PluginRequest::WriteRecord { handle, record }) {
|
||||
Ok(PluginResponse::Bool(b)) => {
|
||||
if b {
|
||||
self.record_cache.borrow_mut().remove(&(handle, app));
|
||||
@@ -631,16 +621,18 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
}
|
||||
match self.doc_view.borrow().as_ref() {
|
||||
Some(info) => match SharedDocumentReader::<DocumentViewData>::open(Path::new(&info.path)) {
|
||||
Ok(reader) => Box::new(reader),
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"[plugin] failed to open document view at {}: {e}",
|
||||
info.path
|
||||
);
|
||||
Box::new(EmptyDocumentReader)
|
||||
Some(info) => {
|
||||
match SharedDocumentReader::<DocumentViewData>::open(Path::new(&info.path)) {
|
||||
Ok(reader) => Box::new(reader),
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"[plugin] failed to open document view at {}: {e}",
|
||||
info.path
|
||||
);
|
||||
Box::new(EmptyDocumentReader)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
None => Box::new(EmptyDocumentReader),
|
||||
}
|
||||
}
|
||||
@@ -657,7 +649,11 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
|
||||
fn try_recv_notification(&mut self) -> Option<(Option<u64>, HostNotification)> {
|
||||
self.notifications.lock().unwrap_or_else(|e| e.into_inner()).try_recv().ok()
|
||||
self.notifications
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner())
|
||||
.try_recv()
|
||||
.ok()
|
||||
}
|
||||
|
||||
fn plugin_request_sender(&self) -> Option<Box<dyn PluginRequestSender>> {
|
||||
@@ -734,7 +730,9 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
|
||||
fn system_variable(&self, name: &str) -> Option<HostSettingValue> {
|
||||
match self.request(PluginRequest::GetSystemVariable { name: name.to_owned() }) {
|
||||
match self.request(PluginRequest::GetSystemVariable {
|
||||
name: name.to_owned(),
|
||||
}) {
|
||||
Ok(PluginResponse::SystemVariable(value)) => value,
|
||||
_ => None,
|
||||
}
|
||||
@@ -767,10 +765,13 @@ impl HostApi for V4PluginHostApi {
|
||||
entities: Vec<EntityType>,
|
||||
) -> Result<(), String> {
|
||||
match self.request(PluginRequest::UpdateEntitiesTransaction {
|
||||
label: label.to_owned(), entities,
|
||||
label: label.to_owned(),
|
||||
entities,
|
||||
}) {
|
||||
Ok(PluginResponse::EntityTransactionResult(result)) => {
|
||||
if result.is_ok() { self.document_cache = OnceCell::new(); }
|
||||
if result.is_ok() {
|
||||
self.document_cache = OnceCell::new();
|
||||
}
|
||||
result
|
||||
}
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
@@ -786,10 +787,15 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
fn solid_operation(&mut self, operation: crate::host::SolidOperation) -> Result<Handle, String> {
|
||||
fn solid_operation(
|
||||
&mut self,
|
||||
operation: crate::host::SolidOperation,
|
||||
) -> Result<Handle, String> {
|
||||
match self.request(PluginRequest::SolidOperation { operation }) {
|
||||
Ok(PluginResponse::SolidResult(result)) => {
|
||||
if result.is_ok() { self.document_cache = OnceCell::new(); }
|
||||
if result.is_ok() {
|
||||
self.document_cache = OnceCell::new();
|
||||
}
|
||||
result
|
||||
}
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
@@ -798,7 +804,10 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_command(&mut self, request: crate::host::CommandRequest) -> Result<crate::host::CommandOutcome, String> {
|
||||
fn run_command(
|
||||
&mut self,
|
||||
request: crate::host::CommandRequest,
|
||||
) -> Result<crate::host::CommandOutcome, String> {
|
||||
match self.request(PluginRequest::RunCommand { request }) {
|
||||
Ok(PluginResponse::CommandResult(result)) => {
|
||||
self.document_cache = OnceCell::new();
|
||||
@@ -810,10 +819,15 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
fn table_operation(&mut self, operation: crate::host::TableOperation) -> Result<Handle, String> {
|
||||
fn table_operation(
|
||||
&mut self,
|
||||
operation: crate::host::TableOperation,
|
||||
) -> Result<Handle, String> {
|
||||
match self.request(PluginRequest::TableOperation { operation }) {
|
||||
Ok(PluginResponse::TableResult(result)) => {
|
||||
if result.is_ok() { self.document_cache = OnceCell::new(); }
|
||||
if result.is_ok() {
|
||||
self.document_cache = OnceCell::new();
|
||||
}
|
||||
result
|
||||
}
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
@@ -823,7 +837,9 @@ impl HostApi for V4PluginHostApi {
|
||||
}
|
||||
|
||||
fn set_selection(&mut self, handles: &[Handle]) -> Result<(), String> {
|
||||
match self.request(PluginRequest::SetSelection { handles: handles.to_vec() }) {
|
||||
match self.request(PluginRequest::SetSelection {
|
||||
handles: handles.to_vec(),
|
||||
}) {
|
||||
Ok(PluginResponse::SelectionResult(result)) => result,
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
Ok(other) => Err(format!("unexpected selection response: {other:?}")),
|
||||
@@ -899,9 +915,7 @@ impl V4Client {
|
||||
});
|
||||
let shared_for_reader = Arc::clone(&shared);
|
||||
let notifications = Arc::new(Mutex::new(notify_rx));
|
||||
std::thread::spawn(move || {
|
||||
reader_thread(reader, shared_for_reader, notify_tx, runner_tx)
|
||||
});
|
||||
std::thread::spawn(move || reader_thread(reader, shared_for_reader, notify_tx, runner_tx));
|
||||
Self {
|
||||
shared,
|
||||
notifications,
|
||||
@@ -1081,7 +1095,10 @@ mod tests {
|
||||
});
|
||||
|
||||
assert!(matches!(first.join().unwrap(), PluginResponse::Bool(true)));
|
||||
assert!(matches!(second.join().unwrap(), PluginResponse::Bool(false)));
|
||||
assert!(matches!(
|
||||
second.join().unwrap(),
|
||||
PluginResponse::Bool(false)
|
||||
));
|
||||
runner.join().unwrap();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,10 @@ pub enum PluginToHostV4 {
|
||||
tab_id: Option<u64>,
|
||||
payload: PluginRequest,
|
||||
},
|
||||
Response { id: u64, payload: HostResponse },
|
||||
Response {
|
||||
id: u64,
|
||||
payload: HostResponse,
|
||||
},
|
||||
Notification(NotificationEnvelope<PluginNotification>),
|
||||
}
|
||||
|
||||
@@ -95,11 +98,17 @@ mod tests {
|
||||
let bytes = bincode::serialize(¬ification).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, notification);
|
||||
let stopped = HostNotification::CommandStateChanged { tab_id: 42, command: None };
|
||||
let stopped = HostNotification::CommandStateChanged {
|
||||
tab_id: 42,
|
||||
command: None,
|
||||
};
|
||||
let bytes = bincode::serialize(&stopped).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, stopped);
|
||||
let changed = HostNotification::DrawingChanged { tab_id: 42, epoch: 7 };
|
||||
let changed = HostNotification::DrawingChanged {
|
||||
tab_id: 42,
|
||||
epoch: 7,
|
||||
};
|
||||
let bytes = bincode::serialize(&changed).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, changed);
|
||||
@@ -109,19 +118,33 @@ mod tests {
|
||||
fn command_request_and_outcome_roundtrip() {
|
||||
use crate::host::{CommandOutcome, CommandRequest};
|
||||
for request in [
|
||||
CommandRequest::Run { line: "LINE 0,0 1,1".into() },
|
||||
CommandRequest::Start { name: "OFFSET".into() },
|
||||
CommandRequest::Point { point: [1.0, 2.0, 3.0] },
|
||||
CommandRequest::Run {
|
||||
line: "LINE 0,0 1,1".into(),
|
||||
},
|
||||
CommandRequest::Start {
|
||||
name: "OFFSET".into(),
|
||||
},
|
||||
CommandRequest::Point {
|
||||
point: [1.0, 2.0, 3.0],
|
||||
},
|
||||
CommandRequest::Text { text: "2".into() },
|
||||
CommandRequest::Token { text: "R".into() },
|
||||
CommandRequest::Entity { handle: codec::Handle::new(9), point: [0.0; 3] },
|
||||
CommandRequest::Entity {
|
||||
handle: codec::Handle::new(9),
|
||||
point: [0.0; 3],
|
||||
},
|
||||
CommandRequest::Selection,
|
||||
CommandRequest::Enter,
|
||||
CommandRequest::Cancel,
|
||||
] {
|
||||
let bytes = bincode::serialize(&PluginRequest::RunCommand { request: request.clone() }).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::RunCommand { request: decoded } if decoded == request));
|
||||
let bytes = bincode::serialize(&PluginRequest::RunCommand {
|
||||
request: request.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::RunCommand { request: decoded } if decoded == request)
|
||||
);
|
||||
}
|
||||
let outcome = CommandOutcome {
|
||||
status: "waiting_input".into(),
|
||||
@@ -137,8 +160,10 @@ mod tests {
|
||||
};
|
||||
for result in [Ok(outcome), Err("refused".to_owned())] {
|
||||
let bytes = bincode::serialize(&PluginResponse::CommandResult(result.clone())).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::CommandResult(decoded) if decoded == result));
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::CommandResult(decoded) if decoded == result)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,19 +180,60 @@ mod tests {
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
TableOperation::LayerModify { config: LayerConfig { name: "Walls".into(), off: Some(true), ..Default::default() } },
|
||||
TableOperation::LayerRename { from: "A".into(), to: "B".into() },
|
||||
TableOperation::LayerDelete { name: "A".into(), erase_objects: true },
|
||||
TableOperation::LayerModify {
|
||||
config: LayerConfig {
|
||||
name: "Walls".into(),
|
||||
off: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
TableOperation::LayerRename {
|
||||
from: "A".into(),
|
||||
to: "B".into(),
|
||||
},
|
||||
TableOperation::LayerDelete {
|
||||
name: "A".into(),
|
||||
erase_objects: true,
|
||||
},
|
||||
TableOperation::LayerSetCurrent { name: "A".into() },
|
||||
TableOperation::TextStyleCreate {
|
||||
config: crate::host::TextStyleConfig { name: "T".into(), height: Some(2.5), oblique_angle: Some(0.2), backward: Some(true), ..Default::default() },
|
||||
config: crate::host::TextStyleConfig {
|
||||
name: "T".into(),
|
||||
height: Some(2.5),
|
||||
oblique_angle: Some(0.2),
|
||||
backward: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
TableOperation::TextStyleModify {
|
||||
config: crate::host::TextStyleConfig {
|
||||
name: "T".into(),
|
||||
font_file: Some("romans".into()),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
TableOperation::DimStyleCreate {
|
||||
name: "D".into(),
|
||||
copy_from: Some("Standard".into()),
|
||||
properties: "{\"dimscale\":2}".into(),
|
||||
},
|
||||
TableOperation::DimStyleModify {
|
||||
name: "D".into(),
|
||||
properties: "{}".into(),
|
||||
},
|
||||
TableOperation::StyleRename {
|
||||
kind: crate::host::TableStyleKind::Text,
|
||||
from: "A".into(),
|
||||
to: "B".into(),
|
||||
},
|
||||
TableOperation::StyleDelete {
|
||||
kind: crate::host::TableStyleKind::Dim,
|
||||
name: "A".into(),
|
||||
},
|
||||
TableOperation::StyleSetCurrent {
|
||||
kind: crate::host::TableStyleKind::Dim,
|
||||
name: "A".into(),
|
||||
},
|
||||
TableOperation::TextStyleModify { config: crate::host::TextStyleConfig { name: "T".into(), font_file: Some("romans".into()), ..Default::default() } },
|
||||
TableOperation::DimStyleCreate { name: "D".into(), copy_from: Some("Standard".into()), properties: "{\"dimscale\":2}".into() },
|
||||
TableOperation::DimStyleModify { name: "D".into(), properties: "{}".into() },
|
||||
TableOperation::StyleRename { kind: crate::host::TableStyleKind::Text, from: "A".into(), to: "B".into() },
|
||||
TableOperation::StyleDelete { kind: crate::host::TableStyleKind::Dim, name: "A".into() },
|
||||
TableOperation::StyleSetCurrent { kind: crate::host::TableStyleKind::Dim, name: "A".into() },
|
||||
TableOperation::BlockCreate {
|
||||
name: "B".into(),
|
||||
entities: vec![codec::Handle::new(4), codec::Handle::new(5)],
|
||||
@@ -175,31 +241,67 @@ mod tests {
|
||||
erase_originals: true,
|
||||
description: Some("d".into()),
|
||||
},
|
||||
TableOperation::BlockModify { name: "B".into(), description: None, explodable: Some(false), scale_uniformly: Some(true) },
|
||||
TableOperation::BlockRename { from: "B".into(), to: "C".into() },
|
||||
TableOperation::BlockModify {
|
||||
name: "B".into(),
|
||||
description: None,
|
||||
explodable: Some(false),
|
||||
scale_uniformly: Some(true),
|
||||
},
|
||||
TableOperation::BlockRename {
|
||||
from: "B".into(),
|
||||
to: "C".into(),
|
||||
},
|
||||
TableOperation::BlockDelete { name: "C".into() },
|
||||
TableOperation::BlockEntityAdd {
|
||||
block: "C".into(),
|
||||
entity: codec::EntityType::Line(codec::entities::Line::new()),
|
||||
},
|
||||
TableOperation::LinetypeCreate { name: "L".into(), description: "d".into(), pattern: vec![1.0, -1.0] },
|
||||
TableOperation::LinetypeModify { name: "L".into(), description: None, pattern: Some(vec![2.0, -2.0]) },
|
||||
TableOperation::LinetypeRename { from: "L".into(), to: "M".into() },
|
||||
TableOperation::LinetypeCreate {
|
||||
name: "L".into(),
|
||||
description: "d".into(),
|
||||
pattern: vec![1.0, -1.0],
|
||||
},
|
||||
TableOperation::LinetypeModify {
|
||||
name: "L".into(),
|
||||
description: None,
|
||||
pattern: Some(vec![2.0, -2.0]),
|
||||
},
|
||||
TableOperation::LinetypeRename {
|
||||
from: "L".into(),
|
||||
to: "M".into(),
|
||||
},
|
||||
TableOperation::LinetypeDelete { name: "M".into() },
|
||||
TableOperation::LayoutCreate { name: "S".into() },
|
||||
TableOperation::LayoutRename { from: "S".into(), to: "T".into() },
|
||||
TableOperation::LayoutRename {
|
||||
from: "S".into(),
|
||||
to: "T".into(),
|
||||
},
|
||||
TableOperation::LayoutDelete { name: "T".into() },
|
||||
TableOperation::LayoutSetCurrent { name: "Model".into() },
|
||||
TableOperation::LayoutSetPage { name: "S".into(), paper_size: Some([420.0, 297.0]), rotation: Some(90), scale: Some([1.0, 50.0]) },
|
||||
TableOperation::LayoutSetCurrent {
|
||||
name: "Model".into(),
|
||||
},
|
||||
TableOperation::LayoutSetPage {
|
||||
name: "S".into(),
|
||||
paper_size: Some([420.0, 297.0]),
|
||||
rotation: Some(90),
|
||||
scale: Some([1.0, 50.0]),
|
||||
},
|
||||
] {
|
||||
let bytes = bincode::serialize(&PluginRequest::TableOperation { operation: operation.clone() }).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::TableOperation { operation: decoded } if decoded == operation));
|
||||
let bytes = bincode::serialize(&PluginRequest::TableOperation {
|
||||
operation: operation.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::TableOperation { operation: decoded } if decoded == operation)
|
||||
);
|
||||
}
|
||||
for result in [Ok(codec::Handle::new(9)), Err("refused".to_owned())] {
|
||||
let bytes = bincode::serialize(&PluginResponse::TableResult(result.clone())).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::TableResult(decoded) if decoded == result));
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::TableResult(decoded) if decoded == result)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,12 +310,29 @@ mod tests {
|
||||
use crate::host::{SolidOperation, SolidPrimitive};
|
||||
for operation in [
|
||||
SolidOperation::Create {
|
||||
primitive: SolidPrimitive::Pyramid { center: [1.0, 2.0, 3.0], radius: 4.0, height: 5.0, sides: 6 },
|
||||
primitive: SolidPrimitive::Pyramid {
|
||||
center: [1.0, 2.0, 3.0],
|
||||
radius: 4.0,
|
||||
height: 5.0,
|
||||
sides: 6,
|
||||
},
|
||||
layer: Some("SOLIDS".into()),
|
||||
},
|
||||
SolidOperation::Transform { handle: codec::Handle::new(7), matrix: [1.0; 16] },
|
||||
SolidOperation::RegionFromProfile { source: codec::Handle::new(3), layer: None, delete_source: true },
|
||||
SolidOperation::EmbedPicture { path: "p.png".into(), origin: [0.0; 3], width: 5.0, layer: None },
|
||||
SolidOperation::Transform {
|
||||
handle: codec::Handle::new(7),
|
||||
matrix: [1.0; 16],
|
||||
},
|
||||
SolidOperation::RegionFromProfile {
|
||||
source: codec::Handle::new(3),
|
||||
layer: None,
|
||||
delete_source: true,
|
||||
},
|
||||
SolidOperation::EmbedPicture {
|
||||
path: "p.png".into(),
|
||||
origin: [0.0; 3],
|
||||
width: 5.0,
|
||||
layer: None,
|
||||
},
|
||||
SolidOperation::Boolean {
|
||||
first: codec::Handle::new(1),
|
||||
second: codec::Handle::new(2),
|
||||
@@ -221,30 +340,52 @@ mod tests {
|
||||
layer: None,
|
||||
keep_operands: false,
|
||||
},
|
||||
SolidOperation::SurfaceFromProfile { source: codec::Handle::new(4), layer: Some("S".into()), delete_source: false },
|
||||
SolidOperation::Extrude { source: codec::Handle::new(5), direction: [0.0, 0.0, 2.0], layer: None, delete_source: true },
|
||||
SolidOperation::SurfaceFromProfile {
|
||||
source: codec::Handle::new(4),
|
||||
layer: Some("S".into()),
|
||||
delete_source: false,
|
||||
},
|
||||
SolidOperation::Extrude {
|
||||
source: codec::Handle::new(5),
|
||||
direction: [0.0, 0.0, 2.0],
|
||||
layer: None,
|
||||
delete_source: true,
|
||||
},
|
||||
] {
|
||||
let bytes = bincode::serialize(&PluginRequest::SolidOperation { operation: operation.clone() }).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::SolidOperation { operation: decoded } if decoded == operation));
|
||||
let bytes = bincode::serialize(&PluginRequest::SolidOperation {
|
||||
operation: operation.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::SolidOperation { operation: decoded } if decoded == operation)
|
||||
);
|
||||
}
|
||||
for result in [Ok(codec::Handle::new(9)), Err("refused".to_owned())] {
|
||||
let bytes = bincode::serialize(&PluginResponse::SolidResult(result.clone())).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::SolidResult(decoded) if decoded == result));
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::SolidResult(decoded) if decoded == result)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_request_and_response_roundtrip() {
|
||||
let request = PluginRequest::SetSelection { handles: vec![codec::Handle::new(9)] };
|
||||
let request = PluginRequest::SetSelection {
|
||||
handles: vec![codec::Handle::new(9)],
|
||||
};
|
||||
let bytes = bincode::serialize(&request).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::SetSelection { handles } if handles == vec![codec::Handle::new(9)]));
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::SetSelection { handles } if handles == vec![codec::Handle::new(9)])
|
||||
);
|
||||
let response = PluginResponse::Selection(vec![codec::Handle::new(9)]);
|
||||
let bytes = bincode::serialize(&response).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::Selection(handles) if handles == vec![codec::Handle::new(9)]));
|
||||
assert!(
|
||||
matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::Selection(handles) if handles == vec![codec::Handle::new(9)])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -26,7 +26,10 @@ macro_rules! vlog {
|
||||
|
||||
/// A frame delivered from the V4 reader thread to the host main thread.
|
||||
pub enum HostIncoming {
|
||||
Response { id: u64, payload: crate::ipc::protocol::HostResponse },
|
||||
Response {
|
||||
id: u64,
|
||||
payload: crate::ipc::protocol::HostResponse,
|
||||
},
|
||||
Request {
|
||||
id: u64,
|
||||
tab_id: Option<u64>,
|
||||
|
||||
Reference in new issue
Block a user