oc2_hlapi_v2 0.2.0

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

use std::convert::Infallible;

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

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

/// A note block's instrument
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum Instrument {
    /// A harp (piano)
    Harp,
    /// A bass drum
    #[serde(rename = "basedrum")]
    BassDrum,
    /// A snare drum
    Snare,
    /// A hi-hat
    Hat,
    /// A bass
    Bass,
    /// A flute
    Flute,
    /// A bell (Glockenspiel)
    Bell,
    /// A guitar
    Guitar,
    /// A chime
    Chime,
    /// A xylophone
    Xylophone,
    /// An iron xylophone
    IronXylophone,
    /// A cowbell
    CowBell,
    /// A didgeridoo
    Didgeridoo,
    /// A synthesizer
    Bit,
    /// A banjo
    Banjo,
    /// An electric piano
    Pling,
    /// A zombie
    Zombie,
    /// A skeleton
    Skeleton,
    /// A creeper
    Creeper,
    /// An ender dragon
    Dragon,
    /// A wither skeleton
    WitherSkeleton,
    /// A piglin
    Piglin,
    /// A custom head
    CustomHead,
}

/// The possible errors for device functions
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum NoteBlockError {
    #[error("HLAPI client error: {0}")]
    /// HLAPI client error
    HlapiClientError(#[from] HlapiClientError),
    #[error("Note out of range")]
    /// Note out of range
    NoteOutOfRange,
}

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

impl NoteBlock {
    /// Gets the note block's current instrument
    pub fn get_instrument(&self) -> Result<Instrument, NoteBlockError> {
        Ok(self.call("getInstrument", &[], &[])?.0)
    }

    /// Sets the note block's current instrument. This is temporary, and will get reset if a note
    /// block detects a change to the block above or below it.
    pub fn set_instrument(&self, instrument: Instrument) -> Result<(), NoteBlockError> {
        self.call::<()>("setInstrument", &[&instrument as _], &[])?;
        Ok(())
    }

    /// Gets the note block's current note
    ///
    /// Note numbers are as shown on the [MC Wiki](https://minecraft.wiki/w/Note_Block)
    pub fn get_note(&self) -> Result<u8, NoteBlockError> {
        Ok(self.call("getNote", &[], &[])?.0)
    }

    /// Sets the note block's current note
    ///
    /// Note numbers are as shown on the [MC Wiki](https://minecraft.wiki/w/Note_Block)
    pub fn set_note(&self, note: u8) -> Result<(), NoteBlockError> {
        if note > 24 {
            return Err(NoteBlockError::NoteOutOfRange);
        }
        self.call::<()>("setNote", &[&note as _], &[])?;
        Ok(())
    }
}

impl DeviceBase for NoteBlock {
    const TYPE: &'static str = "note_block";

    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
    }
}