From c65634e1b3b868f0ef0243a87dbce0a71ca90c1c Mon Sep 17 00:00:00 2001 From: Jika Date: Fri, 31 Oct 2025 22:14:18 +0100 Subject: [PATCH] Moved devices into their own crate --- Cargo.lock | 8 ++ Cargo.toml | 1 + README.md | 4 +- crates/oc2r-core/Readme.md | 65 ++++++++++++-- crates/oc2r-core/docs/index.md | 84 ------------------ crates/oc2r-core/src/lib.rs | 13 +-- crates/oc2r-core/src/rpc.rs | 2 + crates/opencomputers/Cargo.toml | 10 +++ .../wrappers.md => opencomputers/README.md} | 87 +++++++++++-------- .../examples/redstone-events.rs | 3 +- .../examples/redstone.rs | 3 +- .../src}/block_operations.rs | 5 +- .../src/devices => opencomputers/src}/cpu.rs | 5 +- .../src}/energy_storage.rs | 5 +- .../src}/file_import_export.rs | 10 +-- .../src}/fluid_handler.rs | 5 +- .../src}/inventory_operations.rs | 7 +- .../src}/item_handler.rs | 5 +- .../mod.rs => opencomputers/src/lib.rs} | 21 ++--- .../src}/redstone_interface.rs | 5 +- .../devices => opencomputers/src}/robot.rs | 5 +- .../devices => opencomputers/src}/sound.rs | 5 +- 22 files changed, 174 insertions(+), 184 deletions(-) delete mode 100644 crates/oc2r-core/docs/index.md create mode 100644 crates/opencomputers/Cargo.toml rename crates/{oc2r-core/docs/wrappers.md => opencomputers/README.md} (63%) rename crates/{oc2r-core => opencomputers}/examples/redstone-events.rs (97%) rename crates/{oc2r-core => opencomputers}/examples/redstone.rs (93%) rename crates/{oc2r-core/src/devices => opencomputers/src}/block_operations.rs (94%) rename crates/{oc2r-core/src/devices => opencomputers/src}/cpu.rs (57%) rename crates/{oc2r-core/src/devices => opencomputers/src}/energy_storage.rs (90%) rename crates/{oc2r-core/src/devices => opencomputers/src}/file_import_export.rs (91%) rename crates/{oc2r-core/src/devices => opencomputers/src}/fluid_handler.rs (87%) rename crates/{oc2r-core/src/devices => opencomputers/src}/inventory_operations.rs (96%) rename crates/{oc2r-core/src/devices => opencomputers/src}/item_handler.rs (87%) rename crates/{oc2r-core/src/devices/mod.rs => opencomputers/src/lib.rs} (66%) rename crates/{oc2r-core/src/devices => opencomputers/src}/redstone_interface.rs (97%) rename crates/{oc2r-core/src/devices => opencomputers/src}/robot.rs (97%) rename crates/{oc2r-core/src/devices => opencomputers/src}/sound.rs (91%) diff --git a/Cargo.lock b/Cargo.lock index 276ef03..d8e22ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,14 @@ dependencies = [ "miniserde-enum", ] +[[package]] +name = "opencomputers" +version = "0.1.0" +dependencies = [ + "libc", + "oc2r-core", +] + [[package]] name = "proc-macro2" version = "1.0.103" diff --git a/Cargo.toml b/Cargo.toml index 0149ebc..450bd94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,4 @@ codegen-units = 1 [workspace.dependencies] oc2r-core = { path = "crates/oc2r-core" } +opencomputers = { path = "crates/opencomputers" } diff --git a/README.md b/README.md index 0a23587..3b3a645 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Thin, synchronous access to the [OpenComputers II: Reimagined](https://github.co This repository is a workspace is divided into multiple crates: - `crates/oc2r-core`: mirrors the stock Lua helpers (`devices.lua`, `robot.lua`) so you can list devices, invoke methods, -subscribe to events, and work with typed wrappers for common peripherals. +subscribe to events, and work with the low-level RPC primitives. +- `crates/opencomputers`: companion crate that provides strongly typed wrappers for the common HLAPI peripherals. ## Development @@ -26,4 +27,3 @@ Each crates has some examples of how to use it crate are in the `examples` direc Copy the resulting binaries from `target//release/examples/` into Minux (an Import/Export card works well), mark them as executable and then execute them inside the VM. - diff --git a/crates/oc2r-core/Readme.md b/crates/oc2r-core/Readme.md index 1e54015..e757866 100644 --- a/crates/oc2r-core/Readme.md +++ b/crates/oc2r-core/Readme.md @@ -1,13 +1,66 @@ # OC2R-Core -This crate mirrors the stock Lua helpers (`devices.lua`, `robot.lua`) so you can list devices, invoke methods, -subscribe to events, and work with typed wrappers for common peripherals. +Minimal Rust client for the OC2R high-level API. It mirrors the bundled Lua +helper (`devices.lua`) so you can list devices, invoke methods, +and subscribe to events. For ergonomic wrappers on top of these primitives, add +the [`opencomputers`](../opencomputers) crate. -## Documentation +## Getting Started -See [`docs/index.md`](docs/index.md) for the full guide and -[`docs/wrappers.md`](docs/wrappers.md) for device-by-device examples. +1. Install [cross](https://github.com/cross-rs/cross): + ```bash + cargo install cross --git https://github.com/cross-rs/cross + ``` +2. Compile your binary for Minux: + ```bash + cross build --release + ``` +3. Copy `target//release/your-app` onto the Import/Export card and drop + it inside the OC2R VM (for example `/usr/bin/your-app`). + +## Quick Start + +```rust +use oc2r_core::{DeviceBus, DeviceEvent, Result, DEFAULT_DEVICE_PATH}; + +fn main() -> Result<()> { + let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?; + + // Enumerate devices. + let devices = bus.list()?; + println!("Found {} device(s)", devices.len()); + + // Call a method dynamically. + let first = &devices[0].device_id; + let mut device = bus.device(first)?.expect("device disappeared"); + let response = device.call("help", ())?; + println!("help(): {response}"); + + // Subscribe to events and drain one. + device.subscribe()?; + let event = bus.next_event_for(&device_id)?; + println!("{device_id} -> {:#?}", event.payload); + + Ok(()) +} +``` + +## Transport & API Surface + +- **Framing:** Messages are JSON framed with a leading/trailing NUL, exactly + like the Lua RPC client. `DeviceBus::flush` drains stale responses before each + call. +- **Dynamic calls:** Use `Device::call` or `DeviceBus::call`. Anything that + implements `IntoJsonArgs` (tuples, slices, `Vec`) is accepted and converted + into JSON automatically. +- **Subscriptions:** `Device::subscribe` / `Device::unsubscribe` send the + corresponding RPC requests. `DeviceBus::next_event_for(device_id)` waits for + the next matching event; `Device::next_event()` provides a convenience + wrapper. `try_event*` variants check queues without blocking. For a Lua-style + dispatcher, use [`EventLoop`](src/event.rs) which mirrors `event.pull` and + friends. ## Development -The crate targets rust nightly for some size optimisations and relies on `miniserde` and `libc`. +The crate targets rust nightly for size optimisations and relies on `miniserde` +and `libc`. diff --git a/crates/oc2r-core/docs/index.md b/crates/oc2r-core/docs/index.md deleted file mode 100644 index 1944701..0000000 --- a/crates/oc2r-core/docs/index.md +++ /dev/null @@ -1,84 +0,0 @@ -# OC2R Rust Client Guide - -This guide walks through everything you can do with the crate: connecting to -the RPC controller, issuing method calls, handling events, and using the typed -wrappers that mirror `devices.lua`. - -## Getting Started - -1. Install [cross](https://github.com/cross-rs/cross): - ```bash - cargo install cross --git https://github.com/cross-rs/cross - ``` -2. Compile your binary for Minux: - ```bash - cross build --release - ``` -3. Copy `target//release/your-app` onto the Import/Export card and drop - it inside the OC2R VM (e.g. `/usr/bin/your-app`). - -## Quick Start - -```rust -use oc2r_rust::{DeviceBus, DeviceEvent, Result, DEFAULT_DEVICE_PATH}; - -fn main() -> Result<()> { - let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?; - - // Enumerate devices. - let devices = bus.list()?; - println!("Found {} device(s)", devices.len()); - - // Call a method dynamically. - let first = &devices[0].device_id; - let mut device = bus.device(first)?.expect("device disappeared"); - let response = device.call("help", ())?; - println!("help(): {response}"); - - // Subscribe to events and drain one. - device.subscribe()?; - let event = bus.next_event_for(&device_id)?; - println!("{device_id} -> {:#?}", event.payload); - - Ok(()) -} -``` - -## Transport & API Surface - -- **Framing:** Messages are JSON framed with a leading/trailing NUL, exactly like - Lua’s RPC client. `DeviceBus::flush` drains stale responses before each call. -- **Dynamic calls:** Use `Device::call` or `DeviceBus::call`. Anything that - implements `IntoJsonArgs` (tuples, slices, `Vec`) is accepted and converted - into JSON automatically. -- **Subscriptions:** `Device::subscribe` / `Device::unsubscribe` send the - corresponding RPC requests. `DeviceBus::next_event_for(device_id)` waits for - the next matching event; `Device::next_event()` provides a convenience wrapper. - `try_event*` variants check queues without blocking. For a Lua-style - dispatcher, use [`EventLoop`](../src/event.rs) which mirrors `event.pull` and - friends. - -## Typed Wrappers - -To avoid raw JSON, every base device has a wrapper with strongly typed methods: - -- `RedstoneInterface` -- `EnergyStorage` -- `FluidHandler` -- `ItemHandler` -- `Cpu` -- `SoundCard` -- `BlockOperations` -- `InventoryOperations` -- `FileImportExport` -- `Robot` - -Each wrapper exposes Rust-style methods (e.g. `RedstoneInterface::input`, `SoundCard::find`) -built on top of the dynamic API. See [`wrappers.md`](wrappers.md) for detailed -examples and method-by-method coverage. - -## Additional Topics - -- [Device wrapper reference](wrappers.md) -- [Redstone event example](../examples/redstone-events.rs) -- [Lua-style event loop](../src/event.rs) diff --git a/crates/oc2r-core/src/lib.rs b/crates/oc2r-core/src/lib.rs index 5e6885d..f5ce934 100644 --- a/crates/oc2r-core/src/lib.rs +++ b/crates/oc2r-core/src/lib.rs @@ -3,11 +3,12 @@ //! This crate mirrors the behaviour of the bundled Lua `devices.lua` //! helper. It communicates with the OC2R RPC controller over the first //! VirtIO console device (`/dev/hvc0`) and exposes helpers for listing -//! devices, inspecting available methods and invoking them. +//! devices, inspecting available methods and invoking them. For ergonomic +//! wrappers built on this low level API, add the `opencomputers` crate. //! //! # Quick start //! ```no_run -//! use oc2r_rust::{DeviceBus, Result, DEFAULT_DEVICE_PATH}; +//! use oc2r_core::{DeviceBus, Result, DEFAULT_DEVICE_PATH}; //! //! fn main() -> Result<()> { //! let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?; @@ -25,7 +26,6 @@ //! ``` pub mod bus; -pub mod devices; pub mod error; pub mod event; pub mod rpc; @@ -33,14 +33,9 @@ mod transport; mod value; pub use bus::{Device, DeviceBus, DeviceEvent}; -pub use devices::{ - BlockOperations, Cpu, EnergyStorage, FileImportExport, FluidHandler, ImportedFileInfo, - InventoryOperations, ItemHandler, ParseSideError, RedstoneInterface, RedstoneSignal, Robot, - RobotDirection, RobotSide, Side, SoundCard, -}; pub use error::{Error, Result}; pub use event::{EventLoop, Signal}; -pub use rpc::{DeviceEntry, JsonValue, MethodEntry, MethodParameter}; +pub use rpc::{DeviceEntry, JsonArray, JsonNumber, JsonValue, MethodEntry, MethodParameter}; pub use value::{IntoJsonArgs, IntoJsonValue, JsonValueExt}; pub const DEFAULT_DEVICE_PATH: &str = "/dev/hvc0"; diff --git a/crates/oc2r-core/src/rpc.rs b/crates/oc2r-core/src/rpc.rs index 440a809..d3066fb 100644 --- a/crates/oc2r-core/src/rpc.rs +++ b/crates/oc2r-core/src/rpc.rs @@ -71,3 +71,5 @@ pub struct MethodParameter { } pub type JsonValue = json::Value; +pub type JsonArray = json::Array; +pub type JsonNumber = json::Number; diff --git a/crates/opencomputers/Cargo.toml b/crates/opencomputers/Cargo.toml new file mode 100644 index 0000000..f21eef1 --- /dev/null +++ b/crates/opencomputers/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "opencomputers" +version = "0.1.0" +edition = "2024" + +[dependencies] +oc2r-core = { path = "../oc2r-core" } + +[dev-dependencies] +libc = "0.2" diff --git a/crates/oc2r-core/docs/wrappers.md b/crates/opencomputers/README.md similarity index 63% rename from crates/oc2r-core/docs/wrappers.md rename to crates/opencomputers/README.md index fffff7f..d0dbf1d 100644 --- a/crates/oc2r-core/docs/wrappers.md +++ b/crates/opencomputers/README.md @@ -1,26 +1,31 @@ -# Device Wrapper Reference +# opencomputers -Each wrapper mirrors the Lua helper for the corresponding OC2R device and builds -on top of `Device::call`. All examples assume: +Typed wrappers for the OC2R high-level API based on `oc2r-core`. +Each module exposes a safe, idiomatic Rust interface for a specific +device class. + +## Usage Overview + +Every wrapper sits on top of `Device::call`. Typical imports look like: ```rust -use oc2r_rust::{DeviceBus, Result, DEFAULT_DEVICE_PATH}; +use oc2r_core::{DeviceBus, Result, DEFAULT_DEVICE_PATH}; +use opencomputers::*; ``` -Before using any wrapper, attach it: +Attach the device before use: ```rust let mut bus = DeviceBus::connect(DEFAULT_DEVICE_PATH)?; -let mut redstone = oc2r_rust::RedstoneInterface::attach(&mut bus)? +let mut redstone = RedstoneInterface::attach(&mut bus)? .expect("no redstone interface attached"); -// call unsubscribe() once you are done processing events -redstone.subscribe()?; +redstone.subscribe()?; // unsubscribe() once you are done ``` -## Robot +### Robot ```rust -use oc2r_rust::{Robot, RobotDirection}; +use opencomputers::{Robot, RobotDirection}; let mut robot = Robot::attach(&mut bus)?.expect("no robot available"); println!("energy {}/{}", robot.energy()?, robot.capacity()?); @@ -37,10 +42,10 @@ if robot.move_blocking(RobotDirection::Forward)? { robot.turn(RobotDirection::Left)?; ``` -## Redstone +### Redstone Interface ```rust -use oc2r_rust::{RedstoneInterface, RedstoneSignal, Side}; +use opencomputers::{RedstoneInterface, RedstoneSignal, Side}; redstone.set_output_state(Side::East, true)?; let input = redstone.input(Side::East)?; @@ -52,14 +57,15 @@ if let Some(signal) = redstone.try_event()? { } ``` -`Side` implements `FromStr` so strings like "north" can be parsed safely. -Incoming events surface as `RedstoneSignal { side, level }`; see also the -`examples/redstone-events.rs` program. +`Side` implements `FromStr` so strings like "north" parse safely. Incoming +events surface as `RedstoneSignal { side, level }`; see +[`examples/redstone-events.rs`](examples/redstone-events.rs) for a full event +loop. -## Energy Storage +### Energy Storage ```rust -use oc2r_rust::EnergyStorage; +use opencomputers::EnergyStorage; let mut energy = EnergyStorage::attach(&mut bus)?.expect("no energy storage"); println!("{}/{}", energy.energy_stored()?, energy.max_energy_stored()?); @@ -67,10 +73,10 @@ println!("can_extract: {}", energy.can_extract()?); println!("can_receive: {}", energy.can_receive()?); ``` -## Fluid Handler +### Fluid Handler ```rust -use oc2r_rust::FluidHandler; +use opencomputers::FluidHandler; let mut fluids = FluidHandler::attach(&mut bus)?.expect("no fluid handler"); let tanks = fluids.tank_count()? as usize; @@ -81,10 +87,10 @@ for tank in 0..tanks { } ``` -## Item Handler +### Item Handler ```rust -use oc2r_rust::ItemHandler; +use opencomputers::ItemHandler; let mut items = ItemHandler::attach(&mut bus)?.expect("no item handler"); let slots = items.slot_count()? as usize; @@ -95,19 +101,19 @@ for slot in 0..slots { } ``` -## CPU +### CPU ```rust -use oc2r_rust::Cpu; +use opencomputers::Cpu; let mut cpu = Cpu::attach(&mut bus)?.expect("no cpu card"); println!("frequency {} MHz", cpu.frequency()?); ``` -## Sound Card +### Sound Card ```rust -use oc2r_rust::SoundCard; +use opencomputers::SoundCard; let mut sound = SoundCard::attach(&mut bus)?.expect("no sound card"); sound.play_with_volume_and_pitch("minecraft:block.note_block.harp", 0.8, 1.2)?; @@ -115,10 +121,10 @@ let matches = sound.find("note_block")?; println!("found {} sound(s)", matches.len()); ``` -## Block Operations Module +### Block Operations Module ```rust -use oc2r_rust::{BlockOperations, RobotSide}; +use opencomputers::{BlockOperations, RobotSide}; let mut ops = BlockOperations::attach(&mut bus)?.expect("no block module"); ops.excavate_on(RobotSide::Front)?; @@ -129,10 +135,10 @@ if ops.repair()? { } ``` -## Inventory Operations Module +### Inventory Operations Module ```rust -use oc2r_rust::{InventoryOperations, RobotSide}; +use opencomputers::{InventoryOperations, RobotSide}; let mut inv = InventoryOperations::attach(&mut bus)?.expect("no inventory module"); inv.move_items(0, 1, 32)?; @@ -141,10 +147,10 @@ let taken = inv.take_from_slot_on(0, 8, RobotSide::Up)?; println!("taken {taken}"); ``` -## File Import/Export Card +### File Import/Export Card ```rust -use oc2r_rust::FileImportExport; +use opencomputers::FileImportExport; let mut fie = FileImportExport::attach(&mut bus)?.expect("no file card"); fie.reset()?; @@ -154,7 +160,11 @@ fie.finish_export()?; if fie.request_import()? { if let Some(info) = fie.begin_import()? { - println!("importing {} ({} bytes)", info.name.unwrap_or_default(), info.size); + println!( + "importing {} ({} bytes)", + info.name.unwrap_or_default(), + info.size + ); while let Some(bytes) = fie.read_import_chunk()? { // write bytes to disk println!("chunk {} bytes", bytes.len()); @@ -163,9 +173,12 @@ if fie.request_import()? { } ``` -The raw event payloads for these devices can also be obtained via -`Device::next_event`/`DeviceBus::next_event_for` when you need to handle -custom packets. +Device-specific events remain accessible through `Device::next_event` or +`DeviceBus::next_event_for` when you need raw payloads. -Feel free to extend these wrappers or add new ones; each uses the same -`define_wrapper!` macro found in `src/devices/mod.rs`. +## Examples + +- [`examples/redstone.rs`](examples/redstone.rs) — control redstone IO from the + command line. +- [`examples/redstone-events.rs`](examples/redstone-events.rs) — subscribe to + redstone change events. diff --git a/crates/oc2r-core/examples/redstone-events.rs b/crates/opencomputers/examples/redstone-events.rs similarity index 97% rename from crates/oc2r-core/examples/redstone-events.rs rename to crates/opencomputers/examples/redstone-events.rs index 59c8df0..3e507c1 100644 --- a/crates/oc2r-core/examples/redstone-events.rs +++ b/crates/opencomputers/examples/redstone-events.rs @@ -1,4 +1,5 @@ -use oc2r_core::{DEFAULT_DEVICE_PATH, DeviceBus, EventLoop, JsonValueExt, RedstoneInterface, Result}; +use oc2r_core::{DEFAULT_DEVICE_PATH, DeviceBus, EventLoop, JsonValueExt, Result}; +use opencomputers::RedstoneInterface; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; diff --git a/crates/oc2r-core/examples/redstone.rs b/crates/opencomputers/examples/redstone.rs similarity index 93% rename from crates/oc2r-core/examples/redstone.rs rename to crates/opencomputers/examples/redstone.rs index 199fe03..4d7806d 100644 --- a/crates/oc2r-core/examples/redstone.rs +++ b/crates/opencomputers/examples/redstone.rs @@ -1,6 +1,7 @@ // Build with: cross build --release --example redstone -use oc2r_core::{DEFAULT_DEVICE_PATH, DeviceBus, RedstoneInterface, Result, Side}; +use oc2r_core::{DEFAULT_DEVICE_PATH, DeviceBus, Result}; +use opencomputers::{RedstoneInterface, Side}; use std::env; use std::str::FromStr; diff --git a/crates/oc2r-core/src/devices/block_operations.rs b/crates/opencomputers/src/block_operations.rs similarity index 94% rename from crates/oc2r-core/src/devices/block_operations.rs rename to crates/opencomputers/src/block_operations.rs index dae387e..0c5bf7e 100644 --- a/crates/oc2r-core/src/devices/block_operations.rs +++ b/crates/opencomputers/src/block_operations.rs @@ -1,7 +1,6 @@ -use crate::Result; -use crate::value::JsonValueExt; +use oc2r_core::{JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( BlockOperations, "block_operations", "Wrapper for the block operations robot module." diff --git a/crates/oc2r-core/src/devices/cpu.rs b/crates/opencomputers/src/cpu.rs similarity index 57% rename from crates/oc2r-core/src/devices/cpu.rs rename to crates/opencomputers/src/cpu.rs index 8ec0d72..110400a 100644 --- a/crates/oc2r-core/src/devices/cpu.rs +++ b/crates/opencomputers/src/cpu.rs @@ -1,7 +1,6 @@ -use crate::Result; -use crate::value::JsonValueExt; +use oc2r_core::{JsonValueExt, Result}; -crate::devices::define_wrapper!(Cpu, "cpu", "Wrapper exposing CPU metadata."); +crate::define_wrapper!(Cpu, "cpu", "Wrapper exposing CPU metadata."); impl<'bus> Cpu<'bus> { pub fn frequency(&mut self) -> Result { diff --git a/crates/oc2r-core/src/devices/energy_storage.rs b/crates/opencomputers/src/energy_storage.rs similarity index 90% rename from crates/oc2r-core/src/devices/energy_storage.rs rename to crates/opencomputers/src/energy_storage.rs index cfc5cbd..d3ffd4b 100644 --- a/crates/oc2r-core/src/devices/energy_storage.rs +++ b/crates/opencomputers/src/energy_storage.rs @@ -1,7 +1,6 @@ -use crate::Result; -use crate::value::JsonValueExt; +use oc2r_core::{JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( EnergyStorage, "energy_storage", "Wrapper for OC2R energy storage devices." diff --git a/crates/oc2r-core/src/devices/file_import_export.rs b/crates/opencomputers/src/file_import_export.rs similarity index 91% rename from crates/oc2r-core/src/devices/file_import_export.rs rename to crates/opencomputers/src/file_import_export.rs index 4029656..c86f9d3 100644 --- a/crates/oc2r-core/src/devices/file_import_export.rs +++ b/crates/opencomputers/src/file_import_export.rs @@ -1,8 +1,6 @@ -use crate::value::JsonValueExt; -use crate::{Error, JsonValue, Result}; -use miniserde::json::{Array, Number}; +use oc2r_core::{Error, JsonArray, JsonNumber, JsonValue, JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( FileImportExport, "file_import_export", "Wrapper for the file import/export card." @@ -28,8 +26,8 @@ impl<'bus> FileImportExport<'bus> { chunk .iter() .copied() - .map(|byte| JsonValue::Number(Number::U64(byte as u64))) - .collect::(), + .map(|byte| JsonValue::Number(JsonNumber::U64(byte as u64))) + .collect::(), ); self.device.call("writeExportFile", (payload,)).map(|_| ()) } diff --git a/crates/oc2r-core/src/devices/fluid_handler.rs b/crates/opencomputers/src/fluid_handler.rs similarity index 87% rename from crates/oc2r-core/src/devices/fluid_handler.rs rename to crates/opencomputers/src/fluid_handler.rs index 2f380b0..dd0a745 100644 --- a/crates/oc2r-core/src/devices/fluid_handler.rs +++ b/crates/opencomputers/src/fluid_handler.rs @@ -1,7 +1,6 @@ -use crate::value::JsonValueExt; -use crate::{JsonValue, Result}; +use oc2r_core::{JsonValue, JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( FluidHandler, "fluid_handler", "Wrapper for Forge fluid handler devices." diff --git a/crates/oc2r-core/src/devices/inventory_operations.rs b/crates/opencomputers/src/inventory_operations.rs similarity index 96% rename from crates/oc2r-core/src/devices/inventory_operations.rs rename to crates/opencomputers/src/inventory_operations.rs index 8a6f429..0b2e29f 100644 --- a/crates/oc2r-core/src/devices/inventory_operations.rs +++ b/crates/opencomputers/src/inventory_operations.rs @@ -1,8 +1,7 @@ -use crate::Result; -use crate::devices::RobotSide; -use crate::value::JsonValueExt; +use crate::RobotSide; +use oc2r_core::{JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( InventoryOperations, "inventory_operations", "Wrapper for the inventory operations robot module." diff --git a/crates/oc2r-core/src/devices/item_handler.rs b/crates/opencomputers/src/item_handler.rs similarity index 87% rename from crates/oc2r-core/src/devices/item_handler.rs rename to crates/opencomputers/src/item_handler.rs index eff918a..757bb8f 100644 --- a/crates/oc2r-core/src/devices/item_handler.rs +++ b/crates/opencomputers/src/item_handler.rs @@ -1,7 +1,6 @@ -use crate::value::JsonValueExt; -use crate::{JsonValue, Result}; +use oc2r_core::{JsonValue, JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( ItemHandler, "item_handler", "Wrapper for Forge item handler devices." diff --git a/crates/oc2r-core/src/devices/mod.rs b/crates/opencomputers/src/lib.rs similarity index 66% rename from crates/oc2r-core/src/devices/mod.rs rename to crates/opencomputers/src/lib.rs index 6ac215f..f82e937 100644 --- a/crates/oc2r-core/src/devices/mod.rs +++ b/crates/opencomputers/src/lib.rs @@ -1,31 +1,32 @@ +//! Typed OC2R device wrappers built on top of `oc2r-core`. + macro_rules! define_wrapper { ($name:ident, $type_name:literal, $doc:literal) => { #[doc = $doc] pub struct $name<'bus> { - pub(crate) device: crate::Device<'bus>, + pub(crate) device: oc2r_core::Device<'bus>, } impl<'bus> $name<'bus> { pub const TYPE_NAME: &'static str = $type_name; - pub fn attach(bus: &'bus mut crate::DeviceBus) -> crate::Result> { - crate::devices::attach_device(bus, Self::TYPE_NAME) - .map(|opt| opt.map(Self::from_device)) + pub fn attach(bus: &'bus mut oc2r_core::DeviceBus) -> oc2r_core::Result> { + crate::attach_device(bus, Self::TYPE_NAME).map(|opt| opt.map(Self::from_device)) } - pub fn from_device(device: crate::Device<'bus>) -> Self { + pub fn from_device(device: oc2r_core::Device<'bus>) -> Self { Self { device } } - pub fn info(&self) -> &crate::DeviceEntry { + pub fn info(&self) -> &oc2r_core::DeviceEntry { self.device.info() } - pub fn as_device(&mut self) -> &mut crate::Device<'bus> { + pub fn as_device(&mut self) -> &mut oc2r_core::Device<'bus> { &mut self.device } - pub fn into_device(self) -> crate::Device<'bus> { + pub fn into_device(self) -> oc2r_core::Device<'bus> { self.device } } @@ -35,9 +36,9 @@ macro_rules! define_wrapper { pub(crate) use define_wrapper; pub(crate) fn attach_device<'bus>( - bus: &'bus mut crate::DeviceBus, + bus: &'bus mut oc2r_core::DeviceBus, type_name: &str, -) -> crate::Result>> { +) -> oc2r_core::Result>> { match bus.find(type_name)? { Some(entry) => bus.device(&entry.device_id), None => Ok(None), diff --git a/crates/oc2r-core/src/devices/redstone_interface.rs b/crates/opencomputers/src/redstone_interface.rs similarity index 97% rename from crates/oc2r-core/src/devices/redstone_interface.rs rename to crates/opencomputers/src/redstone_interface.rs index 864ec6f..2048bf1 100644 --- a/crates/oc2r-core/src/devices/redstone_interface.rs +++ b/crates/opencomputers/src/redstone_interface.rs @@ -1,9 +1,8 @@ -use crate::value::JsonValueExt; -use crate::{DeviceEvent, Error, Result}; +use oc2r_core::{DeviceEvent, Error, JsonValueExt, Result}; use std::fmt; use std::str::FromStr; -crate::devices::define_wrapper!( +crate::define_wrapper!( RedstoneInterface, "redstone", "Typed wrapper around the HLAPI redstone interface." diff --git a/crates/oc2r-core/src/devices/robot.rs b/crates/opencomputers/src/robot.rs similarity index 97% rename from crates/oc2r-core/src/devices/robot.rs rename to crates/opencomputers/src/robot.rs index d854994..f987164 100644 --- a/crates/oc2r-core/src/devices/robot.rs +++ b/crates/opencomputers/src/robot.rs @@ -1,9 +1,8 @@ -use crate::value::JsonValueExt; -use crate::{Error, JsonValue, Result}; +use oc2r_core::{Error, JsonValue, JsonValueExt, Result}; use std::thread; use std::time::Duration; -crate::devices::define_wrapper!( +crate::define_wrapper!( Robot, "robot", "High level wrapper mirroring the Lua robot helper." diff --git a/crates/oc2r-core/src/devices/sound.rs b/crates/opencomputers/src/sound.rs similarity index 91% rename from crates/oc2r-core/src/devices/sound.rs rename to crates/opencomputers/src/sound.rs index ee60d45..04ec91a 100644 --- a/crates/oc2r-core/src/devices/sound.rs +++ b/crates/opencomputers/src/sound.rs @@ -1,7 +1,6 @@ -use crate::Result; -use crate::value::JsonValueExt; +use oc2r_core::{JsonValueExt, Result}; -crate::devices::define_wrapper!( +crate::define_wrapper!( SoundCard, "sound", "Wrapper around the OC2R sound card HLAPI."