Skip to content

Commit

Permalink
Add missing docs and start checking semver
Browse files Browse the repository at this point in the history
  • Loading branch information
Mossop committed Dec 6, 2024
1 parent 1ac3098 commit c280303
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 9 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,15 @@ jobs:
components: rustfmt, clippy

- name: Clippy
run: cargo clippy --all-features -- --deny "warnings"
run: cargo clippy -- --deny "warnings"

- name: Rustfmt
run: cargo fmt --check

- name: Check for unused dependencies
uses: bnjbvr/cargo-machete@main

- name: Check semver
uses: obi1kenobi/cargo-semver-checks-action@v2
with:
feature-group: default-features
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mcutie"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/Mossop/mcutie"
Expand Down
10 changes: 6 additions & 4 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ impl<const N: usize> Default for Buffer<N> {

impl<const N: usize> Buffer<N> {
/// Creates a new buffer.
pub const fn new() -> Self {
pub(crate) const fn new() -> Self {
Self {
bytes: [0; N],
cursor: 0,
}
}

/// Creates a new buffer and writes the given data into it.
pub fn from(buf: &[u8]) -> Result<Self, Error> {
pub(crate) fn from(buf: &[u8]) -> Result<Self, Error> {
let mut buffer = Self::new();
match buffer.write_all(buf) {
Ok(()) => Ok(buffer),
Expand All @@ -47,7 +47,8 @@ impl<const N: usize> Buffer<N> {
}

#[cfg(feature = "serde")]
pub fn serialize_json<T: serde::Serialize>(
/// Serializes a value into this buffer using JSON.
pub(crate) fn serialize_json<T: serde::Serialize>(
&mut self,
value: &T,
) -> Result<(), serde_json_core::ser::Error> {
Expand All @@ -58,6 +59,7 @@ impl<const N: usize> Buffer<N> {
}

#[cfg(feature = "serde")]
/// Deserializes this buffer using JSON into the given type.
pub fn deserialize_json<'a, T: serde::Deserialize<'a>>(
&'a self,
) -> Result<T, serde_json_core::de::Error> {
Expand All @@ -72,7 +74,7 @@ impl<const N: usize> Buffer<N> {
}

/// Resets the buffer discarding any previously written bytes.
pub fn reset(&mut self) {
pub(crate) fn reset(&mut self) {
self.cursor = 0;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/fmt.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#![macro_use]

#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("The `defmt` and `log` features cannot both be enabled at the same time.");

#[cfg(not(feature = "defmt"))]
use core::fmt;

Expand Down
3 changes: 3 additions & 0 deletions src/homeassistant/binary_sensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{homeassistant::Component, Error, Publishable, Topic};
/// The state of the sensor. Can be easily converted to or from a [`bool`].
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(from = "&str", into = "&'static str")]
#[allow(missing_docs)]
pub enum BinarySensorState {
On,
Off,
Expand Down Expand Up @@ -63,6 +64,7 @@ impl AsRef<[u8]> for BinarySensorState {
/// The type of sensor.
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
#[allow(missing_docs)]
pub enum BinarySensorClass {
Battery,
BatteryCharging,
Expand Down Expand Up @@ -97,6 +99,7 @@ pub enum BinarySensorClass {
/// A binary sensor that can publish a [`BinarySensorState`] status.
#[derive(Serialize)]
pub struct BinarySensor {
/// The type of sensor
pub device_class: Option<BinarySensorClass>,
}

Expand Down
18 changes: 16 additions & 2 deletions src/homeassistant/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{

#[derive(Serialize)]
#[serde(rename_all = "lowercase")]
#[allow(missing_docs)]
pub enum SupportedColorMode {
OnOff,
Brightness,
Expand Down Expand Up @@ -46,7 +47,7 @@ struct SerializedColor {
}

#[derive(Deserialize)]
pub struct LedPayload<'a> {
struct LedPayload<'a> {
state: BinarySensorState,
#[serde(default)]
brightness: Option<u8>,
Expand All @@ -58,8 +59,10 @@ pub struct LedPayload<'a> {
effect: Option<&'a str>,
}

/// The color of the light in various forms.
#[derive(Serialize)]
#[serde(rename_all = "lowercase", tag = "color_mode", content = "color")]
#[allow(missing_docs)]
pub enum Color {
None,
Brightness(u8),
Expand Down Expand Up @@ -106,13 +109,19 @@ pub enum Color {
},
}

/// The state of the light. This can be sent to the broker and received as a
/// command from Home Assistant.
pub struct LightState<'a> {
/// Whether the light is on or off.
pub state: BinarySensorState,
/// The color of the light.
pub color: Color,
/// Any effect that is applied.
pub effect: Option<&'a str>,
}

impl<'a> LightState<'a> {
/// Parses the state from a command payload.
pub fn from_payload(payload: &'a Payload) -> Result<Self, Error> {
let parsed: LedPayload<'a> = match payload.deserialize_json() {
Ok(p) => p,
Expand Down Expand Up @@ -312,9 +321,14 @@ impl Serialize for LightState<'_> {
}
}

/// A light entity
pub struct Light<'a, const C: usize, const E: usize> {
pub command_topic: Topic<&'a str>,
/// A command topic that Home Assistant can use to control the light.
/// It will be sent a [`LightState`] payload.
pub command_topic: Option<Topic<&'a str>>,
/// The color modes supported by the light.
pub supported_color_modes: [SupportedColorMode; C],
/// Any effects that can be used.
pub effects: [&'a str; E],
}

Expand Down
15 changes: 15 additions & 0 deletions src/homeassistant/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ pub trait Component: Serialize {
/// The state to publish.
type State;

/// The platform identifier for this entity. Internal.
fn platform() -> &'static str;

/// Publishes this entity's state to the MQTT broker.
fn publish_state<T: Deref<Target = str>>(
&self,
topic: &Topic<T>,
Expand Down Expand Up @@ -122,11 +124,15 @@ where
/// automatically included.
#[derive(Clone, Copy, Default)]
pub struct Device<'a> {
/// A name to identify the device. If not provided the default device type is
/// used.
pub name: Option<&'a str>,
/// An optional configuration URL for the device.
pub configuration_url: Option<&'a str>,
}

impl Device<'_> {
/// Creates a new default device.
pub const fn new() -> Self {
Self {
name: None,
Expand Down Expand Up @@ -166,11 +172,14 @@ impl Serialize for Device<'_> {
/// included.
#[derive(Clone, Copy, Default, Serialize)]
pub struct Origin<'a> {
/// A name to identify the device's origin. If not provided the default
/// device type is used.
#[serde(serialize_with = "name_or_device")]
pub name: Option<&'a str>,
}

impl Origin<'_> {
/// Creates a new default origin.
pub const fn new() -> Self {
Self { name: None }
}
Expand All @@ -183,10 +192,15 @@ impl Origin<'_> {
/// [Home Assistant MQTT docs](https://www.home-assistant.io/integrations/mqtt/)
/// for information on what some of these properties mean.
pub struct Entity<'a, const A: usize, C: Component> {
/// The device this entity is a part of.
pub device: Device<'a>,
/// The origin of the device.
pub origin: Origin<'a>,
/// An object identifier to allow for entity ID customisation in Home Assistant.
pub object_id: &'a str,
/// An optional unique identifier for the entity.
pub unique_id: Option<&'a str>,
/// A friendly name for the entity.
pub name: &'a str,
/// Specifies the availability topics that Home Assistant will listen to to
/// determine this entity's availability.
Expand Down Expand Up @@ -225,6 +239,7 @@ impl<const A: usize, C: Component> Entity<'_, A, C> {
}

/// A payload representing a device or entity's availability.
#[allow(missing_docs)]
pub enum AvailabilityState {
Online,
Offline,
Expand Down
7 changes: 7 additions & 0 deletions src/homeassistant/sensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{homeassistant::Component, Error, Publishable, Topic};
/// The type of sensor.
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
#[allow(missing_docs)]
pub enum SensorClass {
ApparentPower,
Aqi,
Expand Down Expand Up @@ -66,16 +67,22 @@ pub enum SensorClass {
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SensorStateClass {
/// A measurement at a singe point in time.
Measurement,
/// A cumulative total that can increase or decrease over time.
Total,
/// A cumulative total that can only increase.
TotalIncreasing,
}

/// A binary sensor that can publish a [`f32`] value.
#[derive(Serialize)]
pub struct Sensor<'u> {
/// The type of sensor.
pub device_class: Option<SensorClass>,
/// The type of measurement that this sensor reports.
pub state_class: Option<SensorStateClass>,
/// The unit of measurement for this sensor.
pub unit_of_measurement: Option<&'u str>,
}

Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![deny(unreachable_pub)]
#![warn(missing_docs)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

use core::{ops::Deref, str};

Expand All @@ -15,6 +17,7 @@ use once_cell::sync::OnceCell;
pub use publish::*;
pub use topic::Topic;

// This must come first so the macros are visible
pub(crate) mod fmt;

mod buffer;
Expand Down Expand Up @@ -56,9 +59,13 @@ fn device_type() -> &'static str {
/// Various errors
#[derive(Debug)]
pub enum Error {
/// An IO error occured.
IOError,
/// The operation timed out.
TimedOut,
/// An attempt was made to encode something too large.
TooLarge,
/// A packet or payload could not be decoded or encoded.
PacketError,
}

Expand Down Expand Up @@ -88,6 +95,7 @@ enum ControlMessage {
pub struct McutieReceiver;

impl McutieReceiver {
/// Waits for the next message from the broker.
pub async fn receive(&self) -> MqttMessage {
DATA_CHANNEL.receive().await
}
Expand Down

0 comments on commit c280303

Please sign in to comment.