]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | use std::fmt; |
2 | use std::str; | |
3 | use std::string::FromUtf8Error; | |
4 | ||
5 | use crate::raw::FstType; | |
6 | ||
7 | /// An error that occurred while using a finite state transducer. | |
8 | /// | |
9 | /// This enum is non-exhaustive. New variants may be added to it in | |
10 | /// compatible releases. | |
11 | pub enum Error { | |
12 | /// A version mismatch occurred while reading a finite state transducer. | |
13 | /// | |
14 | /// This occurs when the API version (of the crate) does not match the | |
15 | /// version encoded in the finite state transducer. | |
16 | /// | |
17 | /// When this error is encountered, there are only two ways to fix it: | |
18 | /// | |
19 | /// 1. Change the version of the library to one that is compatible with | |
20 | /// the given finite state transducer. | |
21 | /// 2. Rebuild the finite state transducer. | |
22 | Version { | |
23 | /// The expected version, which is hard-coded into the current version | |
24 | /// of this crate. | |
25 | expected: u64, | |
26 | /// The version read from the finite state transducer. | |
27 | got: u64, | |
28 | }, | |
29 | /// An unexpected error occurred while reading a finite state transducer. | |
30 | /// Usually this occurs because the data is corrupted or is not actually | |
31 | /// a finite state transducer serialized by this library. | |
32 | Format { | |
33 | /// The number of bytes given to the FST constructor. | |
34 | size: usize, | |
35 | }, | |
36 | /// An error that is returned if verification of an FST fails because of a | |
37 | /// checksum mismatch. | |
38 | ChecksumMismatch { | |
39 | /// The checksum that was expected. | |
40 | expected: u32, | |
41 | /// The checksum that was actually computed. | |
42 | got: u32, | |
43 | }, | |
44 | /// An error that is returned if the caller attempts to verify an FST | |
45 | /// that does not have a checksum, as is the case for all FSTs generated | |
46 | /// by this crate before version `0.4`. | |
47 | ChecksumMissing, | |
48 | /// A duplicate key was inserted into a finite state transducer, which is | |
49 | /// not allowed. | |
50 | DuplicateKey { | |
51 | /// The duplicate key. | |
52 | got: Vec<u8>, | |
53 | }, | |
54 | /// A key was inserted out of order into a finite state transducer. | |
55 | /// | |
56 | /// Keys must always be inserted in lexicographic order. | |
57 | OutOfOrder { | |
58 | /// The last key successfully inserted. | |
59 | previous: Vec<u8>, | |
60 | /// The key that caused this error to occur. | |
61 | got: Vec<u8>, | |
62 | }, | |
63 | /// A finite state transducer with an unexpected type was found. | |
64 | /// | |
65 | /// This is not currently used in this crate, but callers may wish to | |
66 | /// employ its use for alternative data structures implemented on top of | |
67 | /// finite state transducers. | |
68 | WrongType { | |
69 | /// The expected finite state transducer type. | |
70 | expected: FstType, | |
71 | /// The type read from a finite state transducer. | |
72 | got: FstType, | |
73 | }, | |
74 | /// An error that occurred when trying to decode a UTF-8 byte key. | |
75 | FromUtf8(FromUtf8Error), | |
76 | /// Hints that destructuring should not be exhaustive. | |
77 | /// | |
78 | /// This enum may grow additional variants, so this makes sure clients | |
79 | /// don't count on exhaustive matching. (Otherwise, adding a new variant | |
80 | /// could break existing code.) | |
81 | #[doc(hidden)] | |
82 | __Nonexhaustive, | |
83 | } | |
84 | ||
85 | impl fmt::Display for Error { | |
86 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
87 | match *self { | |
88 | Error::FromUtf8(ref err) => err.fmt(f), | |
89 | Error::Version { expected, got } => write!( | |
90 | f, | |
91 | "\ | |
92 | Error opening FST: expected API version {}, got API version {}. \ | |
93 | It looks like the FST you're trying to open is either not an FST file or it \ | |
94 | was generated with a different version of the 'fst' crate. You'll either need \ | |
95 | to change the version of the 'fst' crate you're using, or re-generate the | |
96 | FST.", | |
97 | expected, got | |
98 | ), | |
99 | Error::Format { size } => write!( | |
100 | f, | |
101 | "\ | |
102 | Error opening FST with size {} bytes: An unknown error occurred. This \ | |
103 | usually means you're trying to read data that isn't actually an encoded FST.", | |
104 | size | |
105 | ), | |
106 | Error::ChecksumMismatch { expected, got } => write!( | |
107 | f, | |
108 | "FST verification failed: expected checksum of {} but got {}", | |
109 | expected, got, | |
110 | ), | |
111 | Error::ChecksumMissing => write!( | |
112 | f, | |
113 | "FST verification failed: FST does not contain a checksum", | |
114 | ), | |
115 | Error::DuplicateKey { ref got } => write!( | |
116 | f, | |
117 | "Error inserting duplicate key: '{}'.", | |
118 | format_bytes(&*got) | |
119 | ), | |
120 | Error::OutOfOrder { ref previous, ref got } => write!( | |
121 | f, | |
122 | "\ | |
123 | Error inserting out-of-order key: '{}'. (Previous key was '{}'.) Keys must be \ | |
124 | inserted in lexicographic order.", | |
125 | format_bytes(&*got), | |
126 | format_bytes(&*previous) | |
127 | ), | |
128 | Error::WrongType { expected, got } => write!( | |
129 | f, | |
130 | "\ | |
131 | Error opening FST: expected type '{}', got type '{}'.", | |
132 | expected, got | |
133 | ), | |
134 | Error::__Nonexhaustive => unreachable!(), | |
135 | } | |
136 | } | |
137 | } | |
138 | ||
139 | impl fmt::Debug for Error { | |
140 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
141 | fmt::Display::fmt(self, f) | |
142 | } | |
143 | } | |
144 | ||
145 | impl std::error::Error for Error { | |
146 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { | |
147 | match *self { | |
148 | Error::FromUtf8(ref err) => Some(err), | |
149 | _ => None, | |
150 | } | |
151 | } | |
152 | } | |
153 | ||
154 | impl From<FromUtf8Error> for Error { | |
155 | #[inline] | |
156 | fn from(err: FromUtf8Error) -> Error { | |
157 | Error::FromUtf8(err) | |
158 | } | |
159 | } | |
160 | ||
161 | /// Attempt to convert an arbitrary byte string to a more convenient display | |
162 | /// form. | |
163 | /// | |
164 | /// Essentially, try to decode the bytes as UTF-8 and show that. Failing that, | |
165 | /// just show the sequence of bytes. | |
166 | fn format_bytes(bytes: &[u8]) -> String { | |
167 | match str::from_utf8(bytes) { | |
168 | Ok(s) => s.to_owned(), | |
169 | Err(_) => format!("{:?}", bytes), | |
170 | } | |
171 | } |