serde_gff/
error.rs

1//! Реализация структуры, описывающей ошибки кодирования или декодирования GFF
2
3use std::borrow::Cow;
4use std::fmt;
5use std::error;
6use std::io;
7use std::result;
8use std::str::Utf8Error;
9use std::string::FromUtf8Error;
10use serde::de;
11use serde::ser;
12
13use crate::parser::Token;
14use self::Error::*;
15
16/// Виды ошибок, который могут возникнуть при чтении и интерпретации GFF-файла
17#[derive(Debug)]
18pub enum Error {
19  /// Произошла ошибка чтения или записи из/в нижележащего буфера
20  Io(io::Error),
21  /// Произошла ошибка кодирования или декодирования строки, например, из-за использования
22  /// символа, не поддерживаемого кодировкой
23  Encoding(Cow<'static, str>),
24  /// В файле встретилось значение неизвестного типа, хранящее указанное значение
25  UnknownValue {
26    /// Идентификатор типа значения
27    tag: u32,
28    /// Значение, которое было записано в файле для данного тега
29    value: u32
30  },
31  /// Разбор уже завершен
32  ParsingFinished,
33  /// Некорректное значение для метки. Метка не должна превышать по длине 16 байт в UTF-8,
34  /// но указанное значение больше. Ошибка содержит длину текста, который пытаются преобразовать
35  TooLongLabel(usize),
36  /// При десериализации был обнаружен указанный токен, хотя ожидался не он.
37  /// Ожидаемые значения описаны в первом параметре
38  Unexpected(&'static str, Token),
39  /// Ошибка, возникшая при десериализации
40  Deserialize(String),
41  /// Ошибка, возникшая при сериализации
42  Serialize(String),
43}
44/// Тип результата, используемый в методах данной библиотеки
45pub type Result<T> = result::Result<T, Error>;
46
47impl fmt::Display for Error {
48  fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
49    match *self {
50      Io(ref err) => err.fmt(fmt),
51      Encoding(ref msg) => msg.fmt(fmt),
52      UnknownValue { tag, value } => write!(fmt, "Unknown field value (tag: {}, value: {})", tag, value),
53      ParsingFinished => write!(fmt, "Parsing finished"),
54      TooLongLabel(len) => write!(fmt, "Too long label: label can contain up to 16 bytes, but string contains {} bytes in UTF-8", len),
55      Unexpected(ref expected, ref actual) => write!(fmt, "Expected {}, but {:?} found", expected, actual),
56      Deserialize(ref msg) => msg.fmt(fmt),
57      Serialize(ref msg) => msg.fmt(fmt),
58    }
59  }
60}
61
62impl error::Error for Error {
63  fn source(&self) -> Option<&(dyn error::Error + 'static)> {
64    match *self {
65      Io(ref err) => Some(err),
66      _ => None,
67    }
68  }
69}
70
71impl From<io::Error> for Error {
72  fn from(value: io::Error) -> Self { Io(value) }
73}
74/// Реализация для конвертации из ошибок кодирования библиотеки `encodings`
75impl From<Cow<'static, str>> for Error {
76  fn from(value: Cow<'static, str>) -> Self { Encoding(value) }
77}
78impl From<Utf8Error> for Error {
79  fn from(value: Utf8Error) -> Self { Encoding(value.to_string().into()) }
80}
81impl From<FromUtf8Error> for Error {
82  fn from(value: FromUtf8Error) -> Self { Encoding(value.to_string().into()) }
83}
84
85impl de::Error for Error {
86  fn custom<T: fmt::Display>(msg: T) -> Self {
87    Deserialize(msg.to_string())
88  }
89}
90impl ser::Error for Error {
91  fn custom<T: fmt::Display>(msg: T) -> Self {
92    Error::Serialize(msg.to_string())
93  }
94}