use thiserror for more errors
This commit is contained in:
		
							parent
							
								
									0ca1b67cb6
								
							
						
					
					
						commit
						2e8a61b627
					
				
					 4 changed files with 38 additions and 24 deletions
				
			
		| 
						 | 
				
			
			@ -4,7 +4,7 @@ use std::time::Duration;
 | 
			
		|||
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
 | 
			
		||||
use servicepoint::{bitvec::prelude::BitVec, *};
 | 
			
		||||
use servicepoint::*;
 | 
			
		||||
 | 
			
		||||
#[derive(Parser, Debug)]
 | 
			
		||||
struct Cli {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,21 +212,27 @@ pub enum Command {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/// Err values for [Command::try_from].
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
#[derive(Debug, PartialEq, thiserror::Error)]
 | 
			
		||||
pub enum TryFromPacketError {
 | 
			
		||||
    /// the contained command code does not correspond to a known command
 | 
			
		||||
    #[error("The command code {0:?} does not correspond to a known command")]
 | 
			
		||||
    InvalidCommand(u16),
 | 
			
		||||
    /// the expected payload size was n, but size m was found
 | 
			
		||||
    #[error("the expected payload size was {0}, but size {1} was found")]
 | 
			
		||||
    UnexpectedPayloadSize(usize, usize),
 | 
			
		||||
    /// Header fields not needed for the command have been used.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Note that these commands would usually still work on the actual display.
 | 
			
		||||
    #[error("Header fields not needed for the command have been used")]
 | 
			
		||||
    ExtraneousHeaderValues,
 | 
			
		||||
    /// The contained compression code is not known. This could be of disabled features.
 | 
			
		||||
    #[error("The compression code {0:?} does not correspond to a known compression algorithm.")]
 | 
			
		||||
    InvalidCompressionCode(u16),
 | 
			
		||||
    /// Decompression of the payload failed. This can be caused by corrupted packets.
 | 
			
		||||
    #[error("The decompression of the payload failed")]
 | 
			
		||||
    DecompressionFailed,
 | 
			
		||||
    /// The given brightness value is out of bounds
 | 
			
		||||
    #[error("The given brightness value {0} is out of bounds.")]
 | 
			
		||||
    InvalidBrightness(u8),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
use std::fmt::Debug;
 | 
			
		||||
use crate::packet::Packet;
 | 
			
		||||
use std::fmt::Debug;
 | 
			
		||||
 | 
			
		||||
/// A connection to the display.
 | 
			
		||||
///
 | 
			
		||||
| 
						 | 
				
			
			@ -34,20 +34,26 @@ pub enum Connection {
 | 
			
		|||
    /// [servicepoint-websocket-relay]: https://github.com/kaesaecracker/servicepoint-websocket-relay
 | 
			
		||||
    #[cfg(feature = "protocol_websocket")]
 | 
			
		||||
    WebSocket(
 | 
			
		||||
        std::sync::Arc<std::sync::Mutex<tungstenite::WebSocket<
 | 
			
		||||
            tungstenite::stream::MaybeTlsStream<std::net::TcpStream>,
 | 
			
		||||
        >>>,
 | 
			
		||||
        std::sync::Arc<
 | 
			
		||||
            std::sync::Mutex<
 | 
			
		||||
                tungstenite::WebSocket<
 | 
			
		||||
                    tungstenite::stream::MaybeTlsStream<std::net::TcpStream>,
 | 
			
		||||
                >,
 | 
			
		||||
            >,
 | 
			
		||||
        >,
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    /// A fake connection for testing that does not actually send anything.
 | 
			
		||||
    Fake,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
#[derive(Debug, thiserror::Error)]
 | 
			
		||||
pub enum SendError {
 | 
			
		||||
    IoError(std::io::Error),
 | 
			
		||||
    #[error("IO error occurred while sending")]
 | 
			
		||||
    IoError(#[from] std::io::Error),
 | 
			
		||||
    #[cfg(feature = "protocol_websocket")]
 | 
			
		||||
    WebsocketError(tungstenite::Error),
 | 
			
		||||
    #[error("WebSocket error occurred while sending")]
 | 
			
		||||
    WebsocketError(#[from] tungstenite::Error),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Connection {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +109,9 @@ impl Connection {
 | 
			
		|||
 | 
			
		||||
        let request = ClientRequestBuilder::new(uri).into_client_request()?;
 | 
			
		||||
        let (sock, _) = connect(request)?;
 | 
			
		||||
        Ok(Self::WebSocket(std::sync::Arc::new(std::sync::Mutex::new(sock))))
 | 
			
		||||
        Ok(Self::WebSocket(std::sync::Arc::new(std::sync::Mutex::new(
 | 
			
		||||
            sock,
 | 
			
		||||
        ))))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Send something packet-like to the display. Usually this is in the form of a Command.
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +165,9 @@ impl Drop for Connection {
 | 
			
		|||
    fn drop(&mut self) {
 | 
			
		||||
        #[cfg(feature = "protocol_websocket")]
 | 
			
		||||
        if let Connection::WebSocket(sock) = self {
 | 
			
		||||
            _ = sock.try_lock().map(move |mut sock| sock.close(None).unwrap() );
 | 
			
		||||
            _ = sock
 | 
			
		||||
                .try_lock()
 | 
			
		||||
                .map(move |mut sock| sock.close(None).unwrap());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,16 +10,14 @@ use std::collections::HashMap;
 | 
			
		|||
/// The encoding is currently not enforced.
 | 
			
		||||
pub type Cp437Grid = PrimitiveGrid<u8>;
 | 
			
		||||
 | 
			
		||||
/// Errors that can occur when loading CP-437.
 | 
			
		||||
#[derive(Debug, PartialEq)]
 | 
			
		||||
pub enum Cp437LoadError {
 | 
			
		||||
    /// Invalid character in input prevented loading
 | 
			
		||||
    InvalidChar {
 | 
			
		||||
        /// invalid character is at this position in input
 | 
			
		||||
        index: usize,
 | 
			
		||||
        /// the invalid character
 | 
			
		||||
        char: char,
 | 
			
		||||
    },
 | 
			
		||||
/// The error occurring when loading an invalid character
 | 
			
		||||
#[derive(Debug, PartialEq, thiserror::Error)]
 | 
			
		||||
#[error("The character {char:?} at position {index} is not a valid CP437 character")]
 | 
			
		||||
pub struct InvalidCharError {
 | 
			
		||||
    /// invalid character is at this position in input
 | 
			
		||||
    index: usize,
 | 
			
		||||
    /// the invalid character
 | 
			
		||||
    char: char,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Cp437Grid {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +31,7 @@ impl Cp437Grid {
 | 
			
		|||
        value: &str,
 | 
			
		||||
        width: usize,
 | 
			
		||||
        wrap: bool,
 | 
			
		||||
    ) -> Result<Self, Cp437LoadError> {
 | 
			
		||||
    ) -> Result<Self, InvalidCharError> {
 | 
			
		||||
        assert!(width > 0);
 | 
			
		||||
        assert!(!value.is_empty());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +41,7 @@ impl Cp437Grid {
 | 
			
		|||
 | 
			
		||||
            for (index, char) in value.chars().enumerate() {
 | 
			
		||||
                if !char.is_ascii() {
 | 
			
		||||
                    return Err(Cp437LoadError::InvalidChar { index, char });
 | 
			
		||||
                    return Err(InvalidCharError { index, char });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let is_lf = char == '\n';
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +197,7 @@ mod tests {
 | 
			
		|||
    #[test]
 | 
			
		||||
    fn load_ascii_invalid() {
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            Err(Cp437LoadError::InvalidChar {
 | 
			
		||||
            Err(InvalidCharError {
 | 
			
		||||
                char: '🥶',
 | 
			
		||||
                index: 2
 | 
			
		||||
            }),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue