oc2_hlapi_v2 0.2.0

A client for the new version of OpenComputers II's HLAPI
Documentation
//! The sign device and its associated types
//!
//! [OC2 Docs](https://fnuecke.github.io/oc2/manual/en_us/device/sign.html)

use std::convert::Infallible;

use serde::{Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid;

use crate::{
    client::{DeviceBase, HlapiClient, HlapiClientError},
    devices::Color,
};

/// The sides of a sign that can have text on them
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub enum SignSide {
    /// The front of the sign
    Front,
    /// The back of the sign
    Back,
}

#[derive(Debug, Clone)]
/// A sign device
pub struct Sign {
    client: HlapiClient,
    uuid: Uuid,
}

/// The possible errors for device functions
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SignError {
    #[error("HLAPI client error: {0}")]
    /// HLAPI client error
    HlapiClientError(#[from] HlapiClientError),
    #[error("Too many lines of text")]
    /// Too many lines
    TooManyLines,
}

impl Sign {
    /// Gets the color of the text on the given side
    pub fn get_color(&self, side: SignSide) -> Result<Color, SignError> {
        Ok(self.call("getColor", &[&side as _], &[])?.0)
    }

    /// Gets the text on the given side
    pub fn get_text(&self, side: SignSide) -> Result<Vec<String>, SignError> {
        Ok(self.call("getText", &[&side as _], &[])?.0)
    }

    /// Gets whether the text on the given side glows
    pub fn is_glowing(&self, side: SignSide) -> Result<bool, SignError> {
        Ok(self.call("isGlowing", &[&side as _], &[])?.0)
    }

    /// Gets whether the sign is readonly
    pub fn is_readonly(&self) -> Result<bool, SignError> {
        Ok(self.call("isReadonly", &[], &[])?.0)
    }

    /// Sets the text on the given side, up to four lines
    pub fn set_text(&self, side: SignSide, lines: &[&str]) -> Result<(), SignError> {
        if lines.len() > 4 {
            return Err(SignError::TooManyLines);
        }
        self.call::<()>("setText", &[&side as _, &lines as _], &[])?;
        Ok(())
    }
}

impl DeviceBase for Sign {
    const TYPE: &'static str = "sign";

    type Event = Infallible;

    fn new(client: HlapiClient, uuid: Uuid) -> Result<Self, HlapiClientError> {
        Ok(Self { client, uuid })
    }

    fn uuid_base(&self) -> Uuid {
        self.uuid
    }

    fn client(&self) -> &HlapiClient {
        &self.client
    }
}