chessnut_move/lib.rs
1// Copyright 2026 Daymon Littrell-Reyes
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![cfg_attr(not(feature = "std"), no_std)]
16#![deny(missing_docs)]
17#![deny(rustdoc::broken_intra_doc_links)]
18//! Typed, transport-independent SDK for Chessnut Move boards.
19//!
20//! The crate separates the board's byte protocol from Bluetooth I/O. The
21//! [`protocol`] module provides typed commands and decoded board data, while
22//! [`transport`] provides runtime-neutral session traits and optional adapters.
23//!
24//! Includes support for `no_std` environments, as well as fully featured [Tokio] and `async` based
25//! projects.
26//!
27//! # Features
28//!
29//! - `std` enables standard-library support and is enabled by default.
30//! - `async` enables `transport::AsyncBoard` and is enabled by default.
31//! - `blocking` enables `transport::BlockingBoard`.
32//! - `btleplug` enables `transport::btleplug::BtleplugTransport`, providing support for [btleplug].
33//! - `tokio` enables the actor API in `transport::tokio`.
34//! - `tracing` emits structured spans and events through [tracing]. This
35//! feature also enables `alloc`, but does not install a subscriber.
36//!
37//! Disable default features to use the protocol types in `no_std`
38//! environments.
39//!
40//! # Tracing
41//!
42//! Enable the `tracing` feature to emit structured spans and events from
43//! protocol decoding, transport I/O, session lifecycle operations, actor
44//! queries, and recoverable failures. The crate does not install a
45//! [subscriber], so applications retain control over formatting, filtering,
46//! and collection.
47//!
48//! Event targets follow the Rust module path, such as
49//! `chessnut_move::transport::tokio`. Routine command and notification traffic
50//! is emitted at `trace`, lifecycle and query state at `debug` or `info`, and
51//! failures at `warn` or `error`. Raw command and notification payloads are not
52//! recorded.
53//!
54//! In a standard application, a [`tracing-subscriber`] formatter can be
55//! installed before connecting:
56//!
57//! ```no_run
58//! tracing_subscriber::fmt()
59//! .with_env_filter("chessnut_move=debug")
60//! .init();
61//! ```
62//!
63//! In `no_std` environments, the `tracing` feature requires `alloc` and can
64//! emit to any compatible collector supplied by the application.
65//!
66//! # Examples
67//!
68//! Commands are typed values that can be prepared before a board is connected.
69//! This example creates an LED pattern that can be sent through any supported
70//! board session:
71//!
72//! ```
73//! use chessnut_move::protocol::{
74//! Command, File, LedColor, LedPattern, Rank, Square,
75//! };
76//!
77//! let mut leds = LedPattern::default();
78//! leds.set_color(Square::new(File::E, Rank::Four), LedColor::Green);
79//! leds.set_color(Square::new(File::E, Rank::Five), LedColor::Green);
80//!
81//! let show_move = Command::set_leds(&leds);
82//! assert_eq!(show_move.bytes().len(), 34);
83//! ```
84//!
85//! [Tokio]: https://docs.rs/tokio/latest/tokio/
86//! [btleplug]: https://docs.rs/btleplug/latest/btleplug/
87//! [subscriber]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html
88//! [tracing]: https://docs.rs/tracing/latest/tracing/
89//! [`tracing-subscriber`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/
90#![cfg_attr(
91 feature = "async",
92 doc = r#"
93# Async session
94
95The default async API owns a connected transport for the complete board
96session:
97
98```no_run
99use chessnut_move::protocol::{BoardEvent, Command, LedColor, LedPattern};
100use chessnut_move::transport::{AsyncTransport, Board, BoardError};
101
102async fn run<T: AsyncTransport>(
103 transport: T,
104) -> Result<(), BoardError<T::Error>> {
105 let mut board = Board::new(transport);
106 board.initialize().await?;
107
108 board.send(&Command::set_leds(&LedPattern::all(LedColor::Off))).await?;
109 if let BoardEvent::PositionChanged(position) = board.next_event().await? {
110 println!("position: {position:?}");
111 }
112
113 board.shutdown().await
114}
115```
116"#
117)]
118
119#[macro_use]
120mod instrumentation;
121
122/// Typed commands, decoded notifications, and chessboard values.
123pub mod protocol;
124
125/// Runtime-neutral board sessions and optional Bluetooth adapters.
126pub mod transport;