Buttplug sex toy control library
1// Buttplug Rust Source Code File - See https://buttplug.io for more info.
2//
3// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved.
4//
5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
6// for full license information.
7
8//! Handles client sessions, as well as discovery and communication with hardware.
9//!
10//! The Buttplug Server is just a thin frontend for device connection and communication. The server
11//! itself doesn't do much other than configuring the device system and handling a few non-device
12//! related tasks like [initial connection
13//! handshake](https://buttplug-spec.docs.buttplug.io/architecture.html#stages) and system timeouts.
14//! Once a connection is made from a [ButtplugClient](crate::client::ButtplugClient) to a
15//! [ButtplugServer], the server mostly acts as a pass-thru frontend to the [DeviceManager].
16//!
17//! ## Server Lifetime
18//!
19//! The server has following lifetime stages:
20//!
21//! - Configuration
22//! - This happens across the [ButtplugServerBuilder], as well as the [ButtplugServer] instance it
23//! returns. During this time, we can specify attributes of the server like its name and if it
24//! will have a ping timer. It also allows for addition of protocols and device configurations
25//! to the system, either via configuration files or through manual API calls.
26//! - Connection
27//! - After configuration is done, the server can be put into a listening mode (assuming
28//! [RemoteServer](ButtplugRemoteServer) is being used. for [in-process
29//! servers](crate::connector::ButtplugInProcessClientConnector), the client own the server and just
30//! connects to it directly). At this point, a [ButtplugClient](crate::client::ButtplugClient)
31//! can connect and start the
32//! [handshake](https://buttplug-spec.docs.buttplug.io/architecture.html#stages) process.
33//! - Pass-thru
34//! - Once the handshake has succeeded, the server basically becomes a pass-thru to the
35//! [DeviceManager], which manages discovery of and communication with devices. The only thing
36//! the server instance manages at this point is ownership of the [DeviceManager] and
37//! ping timer, but doesn't really do much itself. The server remains in this state until the
38//! connection to the client is severed, at which point all devices connected to the device
39//! manager will be stopped.
40//! - Disconnection
41//! - The server can be put back in Connection mode without being recreated after disconnection,
42//! to listen for another client connection while still maintaining connection to whatever
43//! devices the [DeviceManager] has.
44//! - Destruction
45//! - If the server object is dropped, all devices are stopped and disconnected as part
46//! of the [DeviceManager] teardown.
47
48#[macro_use]
49extern crate log;
50
51#[macro_use]
52extern crate buttplug_derive;
53
54#[macro_use]
55extern crate strum_macros;
56
57pub mod connector;
58pub mod device;
59pub mod message;
60mod ping_timer;
61mod server;
62mod server_builder;
63mod server_message_conversion;
64
65pub use server::ButtplugServer;
66pub use server_builder::ButtplugServerBuilder;
67
68use futures::future::BoxFuture;
69use thiserror::Error;
70
71use buttplug_core::{
72 errors::{ButtplugDeviceError, ButtplugError},
73 message::ButtplugServerMessageV4,
74};
75
76/// Result type for Buttplug Server methods, as the server will always communicate in
77/// [ButtplugServerMessage] instances in order to follow the [Buttplug
78/// Spec](http://buttplug-spec.docs.buttplug.io).
79pub type ButtplugServerResult = Result<ButtplugServerMessageV4, ButtplugError>;
80/// Future type for Buttplug Server futures, as the server will always communicate in
81/// [ButtplugServerMessage] instances in order to follow the [Buttplug
82/// Spec](http://buttplug-spec.docs.buttplug.io).
83pub type ButtplugServerResultFuture = BoxFuture<'static, ButtplugServerResult>;
84
85/// Error enum for Buttplug Server configuration errors.
86#[derive(Error, Debug)]
87pub enum ButtplugServerError {
88 /// DeviceConfigurationManager could not be built.
89 #[error("The DeviceConfigurationManager could not be built: {0}")]
90 DeviceConfigurationManagerError(ButtplugDeviceError),
91 /// DeviceCommunicationManager type has already been added to the system.
92 #[error("DeviceCommunicationManager of type {0} has already been added.")]
93 DeviceCommunicationManagerTypeAlreadyAdded(String),
94 /// Protocol has already been added to the system.
95 #[error("Buttplug Protocol of type {0} has already been added to the system.")]
96 ProtocolAlreadyAdded(String),
97 /// Requested protocol has not been registered with the system.
98 #[error("Buttplug Protocol of type {0} does not exist in the system and cannot be removed.")]
99 ProtocolDoesNotExist(String),
100}