magic_string_rain 0.3.5

magic string
Documentation
use std::fmt::Formatter;
use std::{
  fmt, io, result,
  string::{self, FromUtf8Error},
};

#[derive(Debug, Clone, PartialEq)]
pub enum MagicStringErrorType {
  IOError,
  UTF8Error,

  JSONSerializationError,

  VlqUnexpectedEof,
  VlqInvalidBase64,
  VlqOverflow,

  RegexSyntaxError,
  RegexCompiledTooBig,
  RegexUnknownError,

  MagicStringOutOfRangeError,
  MagicStringCrossChunkError,
  MagicStringDoubleSplitError,
  MagicStringDoubleEditError,
  MagicStringUnknownError,

  Default,
}

pub type Result<T = ()> = result::Result<T, Error>;

#[derive(Debug, PartialEq)]
pub struct Error {
  pub error_type: MagicStringErrorType,
  pub reason: Option<String>,
}

impl Default for Error {
  fn default() -> Self {
    Self {
      error_type: MagicStringErrorType::Default,
      reason: None,
    }
  }
}

impl Error {
  pub fn new(error_type: MagicStringErrorType) -> Self {
    Self {
      error_type,
      reason: None,
    }
  }

  pub fn new_with_reason(error_type: MagicStringErrorType, reason: &str) -> Self {
    Self {
      error_type,
      reason: Some(String::from(reason)),
    }
  }
}

impl fmt::Display for Error {
  #[inline]
  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    if let Some(ref reason) = self.reason {
      write!(f, "{:?}, {}", self.error_type, reason)
    } else {
      write!(f, "{:?}", self.error_type)
    }
  }
}

impl From<io::Error> for Error {
  #[inline]
  fn from(_: io::Error) -> Self {
    Error::new(MagicStringErrorType::IOError)
  }
}

impl From<vlq::Error> for Error {
  #[inline]
  fn from(err: vlq::Error) -> Self {
    match err {
      vlq::Error::UnexpectedEof => Error::new(MagicStringErrorType::VlqUnexpectedEof),
      vlq::Error::InvalidBase64(_) => Error::new(MagicStringErrorType::VlqInvalidBase64),
      vlq::Error::Overflow => Error::new(MagicStringErrorType::VlqOverflow),
    }
  }
}

impl From<regex::Error> for Error {
  #[inline]
  fn from(err: regex::Error) -> Self {
    match err {
      regex::Error::Syntax(_) => Error::new(MagicStringErrorType::RegexSyntaxError),
      regex::Error::CompiledTooBig(_) => Error::new(MagicStringErrorType::RegexCompiledTooBig),
      _ => Error::new(MagicStringErrorType::RegexUnknownError),
    }
  }
}

impl From<string::FromUtf8Error> for Error {
  #[inline]
  fn from(_: FromUtf8Error) -> Self {
    Error::new(MagicStringErrorType::UTF8Error)
  }
}

impl From<serde_json::Error> for Error {
  #[inline]
  fn from(_: serde_json::Error) -> Self {
    Error::new(MagicStringErrorType::JSONSerializationError)
  }
}

#[cfg(feature = "node-api")]
impl From<Error> for napi::Error {
  #[inline]
  fn from(err: Error) -> Self {
    let mut reason = String::from("[magic-string] ");

    match err.error_type {
      MagicStringErrorType::IOError => {
        reason.push_str("IO Error");
      }
      MagicStringErrorType::UTF8Error => {
        reason.push_str("UTF8 Encoding Error");
      }

      MagicStringErrorType::JSONSerializationError => {
        reason.push_str("JSON Serialization Error");
      }

      MagicStringErrorType::VlqUnexpectedEof => {
        reason.push_str("Vlq Unexpected Eof");
      }
      MagicStringErrorType::VlqInvalidBase64 => {
        reason.push_str("Vlq Unexpected Base64");
      }
      MagicStringErrorType::VlqOverflow => {
        reason.push_str("Vlq Overflow");
      }

      MagicStringErrorType::RegexSyntaxError => {
        reason.push_str("Regex Syntax Error");
      }
      MagicStringErrorType::RegexCompiledTooBig => {
        reason.push_str("Regex Compiled Too Big");
      }
      MagicStringErrorType::RegexUnknownError => {
        reason.push_str("Regex Unknown Error");
      }

      MagicStringErrorType::MagicStringOutOfRangeError => {
        reason.push_str("Magic String Out of Range Error");
      }
      MagicStringErrorType::MagicStringCrossChunkError => {
        reason.push_str("Magic String Cross Chunk Error");
      }
      MagicStringErrorType::MagicStringDoubleSplitError => {
        reason.push_str("Magic String Double Split Error");
      }
      MagicStringErrorType::MagicStringUnknownError => {
        reason.push_str("Magic encountered an unknown error, please file an issue");
      }
      MagicStringErrorType::MagicStringDoubleEditError => {
        reason.push_str("Magic String Double Edit Error");
      }

      MagicStringErrorType::Default => {
        reason.push_str(
          "Default Error should never been thrown to the user end, please file an issue.",
        );
      }
    }

    if let Some(r) = err.reason {
      reason.push_str(", ");
      reason.push_str(&r[..]);
    }

    napi::Error::new(napi::Status::GenericFailure, reason)
  }
}