Skip to main content

persy/
error.rs

1use core::panic;
2use std::{borrow::Cow, fmt::Display, io, str};
3use thiserror::Error;
4
5use crate::id::{PersyId, RecRef};
6
7pub(crate) type PERes<T> = Result<T, GenericError>;
8
9/// Wrapper enum for all the possible Persy errors,
10///
11/// All the public functions use this enum as error return type
12/// specialized with the specific error for the function.
13///
14/// to implement a catch all error for forward just implement a from
15/// as follow
16/// ```
17/// enum YourError {
18///     Persy(persy::PersyError),
19/// }
20///
21/// impl<T: Into<persy::PersyError>> From<persy::PE<T>> for YourError {
22///     fn from(err: persy::PE<T>) -> YourError {
23///         YourError::Persy(err.error().into())
24///    }
25/// }
26///
27/// ```
28///
29#[derive(Debug)]
30pub enum PE<T: Into<PersyError>> {
31    PE(T),
32}
33
34impl<T: std::error::Error + Display + Into<PersyError>> std::error::Error for PE<T> {
35    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
36        match self {
37            PE::PE(e) => e.source(),
38        }
39    }
40}
41
42impl<T: Display + Into<PersyError>> Display for PE<T> {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        match self {
45            PE::PE(e) => e.fmt(f),
46        }
47    }
48}
49
50impl<T: Into<PersyError>> PE<T> {
51    pub fn error(self) -> T {
52        match self {
53            PE::PE(e) => e,
54        }
55    }
56
57    pub fn persy_error(self) -> PersyError {
58        match self {
59            PE::PE(e) => e.into(),
60        }
61    }
62}
63
64impl<T: Into<PersyError>> std::ops::Deref for PE<T> {
65    type Target = T;
66    fn deref(&self) -> &Self::Target {
67        match self {
68            PE::PE(e) => e,
69        }
70    }
71}
72impl<S, D> From<S> for PE<D>
73where
74    S: Into<D>,
75    D: Into<PersyError>,
76    S: Into<PersyError>,
77{
78    fn from(source: S) -> Self {
79        PE::PE(source.into())
80    }
81}
82
83/// Enum of all possible errors from Persy
84#[derive(Debug, Error)]
85#[non_exhaustive]
86pub enum PersyError {
87    #[error("IO Error: {from} ")]
88    Io { from: io::Error },
89    #[error("String decoding error: {0}")]
90    DecodingUtf8(str::Utf8Error),
91    #[error("Failure acquiring lock for poisoning")]
92    DecodingDataEncoding(data_encoding::DecodeError),
93    #[error("Version Not Latest")]
94    VersionNotLatest,
95    #[error("Record Not Found {0}")]
96    RecordNotFound(PersyId),
97    #[error("Segment Not Found")]
98    SegmentNotFound,
99    #[error("Segment Already Exists")]
100    SegmentAlreadyExists,
101    #[error("Index Already Exists")]
102    IndexAlreadyExists,
103    #[error("Create and drop of a segment in the same transaction is not allowed")]
104    CannotDropSegmentCreatedInTx,
105    #[error("Create and drop of a index in the same transaction is not allowed")]
106    CannotDropIndexCreatedInTx,
107    #[error("Index Not Found")]
108    IndexNotFound,
109    #[error("Index method type mismatch persistent types: {0}")]
110    IndexTypeMismatch(Cow<'static, str>),
111    #[error("Found duplicate key:{0} for index: {1}")]
112    IndexDuplicateKey(String, String),
113    #[error("Reached the limit of retry changing the index")]
114    ReachedLimitOfRetry,
115    #[error("Timeout acquiring the data locks for the transaction")]
116    TransactionTimeout,
117    #[error("The id '{0}' has no valid format")]
118    InvalidId(String),
119    #[error("The id '{0}' has no valid format")]
120    InvalidPersyId(RecRef),
121    #[error("{0}")]
122    InitError(String),
123    #[error("Failure acquiring file lock: {0}")]
124    AlreadyInUse(io::Error),
125    #[error("File do not exists")]
126    NotExists,
127    #[error("Cannot create a new file already exists")]
128    AlreadyExists,
129    #[error("The file specified is not a Persy file")]
130    NotPersyFile,
131    #[error("Size of the record is too big")]
132    RecordToBig,
133    #[error("The key or the value are over the allowed size limit")]
134    KeyOrValueTooBig,
135    #[error("Varint Decoding error: {0}")]
136    VarIntError(#[from] unsigned_varint::io::ReadError),
137}
138
139#[derive(Debug, Error)]
140#[non_exhaustive]
141pub enum BeginTransactionError {
142    #[error(transparent)]
143    Generic(#[from] GenericError),
144    #[error("Transaction Id must be maximum 512 bytes")]
145    InvalidTransactionId,
146}
147
148impl From<BeginTransactionError> for PersyError {
149    fn from(e: BeginTransactionError) -> Self {
150        match e {
151            BeginTransactionError::Generic(e) => e.into(),
152            BeginTransactionError::InvalidTransactionId => {
153                PersyError::InvalidId("Transaction Id must be maximum 512 bytes".to_owned())
154            }
155        }
156    }
157}
158
159#[derive(Debug, Error)]
160#[non_exhaustive]
161pub enum CreateSegmentError {
162    #[error(transparent)]
163    Generic(#[from] GenericError),
164    #[error("Segment Already Exists")]
165    SegmentAlreadyExists,
166}
167
168#[derive(Debug, Error)]
169#[non_exhaustive]
170pub enum DropIndexError {
171    #[error(transparent)]
172    Generic(#[from] GenericError),
173    #[error("Index Not Found")]
174    IndexNotFound,
175    #[error("Create and drop of a index in the same transaction is not allowed")]
176    CannotDropIndexCreatedInTx,
177}
178
179impl From<DropSegmentError> for DropIndexError {
180    fn from(e: DropSegmentError) -> Self {
181        match e {
182            DropSegmentError::Generic(ee) => DropIndexError::Generic(ee),
183            DropSegmentError::SegmentNotFound => DropIndexError::IndexNotFound,
184            DropSegmentError::CannotDropSegmentCreatedInTx => DropIndexError::CannotDropIndexCreatedInTx,
185        }
186    }
187}
188
189impl From<DropIndexError> for PersyError {
190    fn from(e: DropIndexError) -> Self {
191        match e {
192            DropIndexError::Generic(e) => e.into(),
193            DropIndexError::IndexNotFound => PersyError::IndexNotFound,
194            DropIndexError::CannotDropIndexCreatedInTx => PersyError::CannotDropIndexCreatedInTx,
195        }
196    }
197}
198
199#[derive(Debug, Error)]
200#[non_exhaustive]
201pub enum DropSegmentError {
202    #[error(transparent)]
203    Generic(#[from] GenericError),
204    #[error("Segment Not Found")]
205    SegmentNotFound,
206    #[error("Create and drop of a segment in the same transaction is not allowed")]
207    CannotDropSegmentCreatedInTx,
208}
209
210impl From<SegmentError> for DropSegmentError {
211    fn from(e: SegmentError) -> Self {
212        match e {
213            SegmentError::Generic(ee) => DropSegmentError::Generic(ee),
214            SegmentError::SegmentNotFound => DropSegmentError::SegmentNotFound,
215        }
216    }
217}
218
219impl From<DropSegmentError> for PersyError {
220    fn from(e: DropSegmentError) -> Self {
221        match e {
222            DropSegmentError::Generic(e) => e.into(),
223            DropSegmentError::SegmentNotFound => PersyError::SegmentNotFound,
224            DropSegmentError::CannotDropSegmentCreatedInTx => PersyError::CannotDropSegmentCreatedInTx,
225        }
226    }
227}
228
229#[derive(Debug, Error)]
230#[non_exhaustive]
231pub enum SegmentError {
232    #[error(transparent)]
233    Generic(#[from] GenericError),
234    #[error("Segment Not Found")]
235    SegmentNotFound,
236}
237
238impl From<SegmentError> for PersyError {
239    fn from(e: SegmentError) -> Self {
240        match e {
241            SegmentError::Generic(e) => e.into(),
242            SegmentError::SegmentNotFound => PersyError::SegmentNotFound,
243        }
244    }
245}
246
247#[derive(Debug, Error)]
248#[non_exhaustive]
249pub enum ReadError {
250    #[error(transparent)]
251    Generic(#[from] GenericError),
252    #[error("Segment Not Found")]
253    SegmentNotFound,
254    #[error("The id '{0}' has no valid format")]
255    InvalidPersyId(RecRef),
256}
257
258impl From<ReadError> for PersyError {
259    fn from(e: ReadError) -> Self {
260        match e {
261            ReadError::Generic(e) => e.into(),
262            ReadError::SegmentNotFound => PersyError::SegmentNotFound,
263            ReadError::InvalidPersyId(e) => PersyError::InvalidPersyId(e),
264        }
265    }
266}
267
268impl From<SegmentError> for ReadError {
269    fn from(e: SegmentError) -> Self {
270        match e {
271            SegmentError::Generic(e) => ReadError::Generic(e),
272            SegmentError::SegmentNotFound => ReadError::SegmentNotFound,
273        }
274    }
275}
276
277#[derive(Debug, Error)]
278#[non_exhaustive]
279pub enum CreateIndexError {
280    #[error(transparent)]
281    Generic(#[from] GenericError),
282    #[error("Index Already Exists")]
283    IndexAlreadyExists,
284}
285
286impl From<CreateSegmentError> for CreateIndexError {
287    fn from(e: CreateSegmentError) -> Self {
288        match e {
289            CreateSegmentError::Generic(ee) => CreateIndexError::Generic(ee),
290            CreateSegmentError::SegmentAlreadyExists => CreateIndexError::IndexAlreadyExists,
291        }
292    }
293}
294
295impl From<InsertError> for CreateIndexError {
296    fn from(e: InsertError) -> Self {
297        match e {
298            InsertError::Generic(ee) => CreateIndexError::Generic(ee),
299            InsertError::SegmentNotFound => panic!("Segment should be created while creating index, impossible error"),
300            InsertError::RecordToBig => panic!("Record size should never fail in index creation"),
301        }
302    }
303}
304
305impl From<CreateIndexError> for PersyError {
306    fn from(e: CreateIndexError) -> Self {
307        match e {
308            CreateIndexError::Generic(er) => er.into(),
309            CreateIndexError::IndexAlreadyExists => PersyError::IndexAlreadyExists,
310        }
311    }
312}
313
314#[derive(Debug, Error)]
315#[non_exhaustive]
316pub enum IndexError {
317    #[error(transparent)]
318    Generic(#[from] GenericError),
319    #[error("Index Not Found")]
320    IndexNotFound,
321}
322
323impl From<IndexError> for PersyError {
324    fn from(e: IndexError) -> Self {
325        match e {
326            IndexError::Generic(e) => e.into(),
327            IndexError::IndexNotFound => PersyError::IndexNotFound,
328        }
329    }
330}
331
332impl From<SegmentError> for IndexError {
333    fn from(e: SegmentError) -> Self {
334        match e {
335            SegmentError::Generic(ex) => IndexError::Generic(ex),
336            SegmentError::SegmentNotFound => IndexError::IndexNotFound,
337        }
338    }
339}
340
341impl From<ReadError> for IndexError {
342    fn from(e: ReadError) -> Self {
343        match e {
344            ReadError::Generic(ex) => IndexError::Generic(ex),
345            ReadError::SegmentNotFound => IndexError::IndexNotFound,
346            ReadError::InvalidPersyId(_) => unreachable!(),
347        }
348    }
349}
350
351#[derive(Debug, Error)]
352#[non_exhaustive]
353pub enum GenericError {
354    #[error("IO Error: {from}")]
355    Io { from: io::Error },
356    #[error("String decoding error: {0}")]
357    DecodingUtf8(#[from] str::Utf8Error),
358    #[error("Varint Decoding error: {0}")]
359    VarIntError(#[from] unsigned_varint::io::ReadError),
360}
361impl From<io::Error> for GenericError {
362    fn from(err: io::Error) -> Self {
363        #[cfg(feature = "test_backtraces")]
364        eprintln!("{:?}", backtrace::Backtrace::new());
365        GenericError::Io { from: err }
366    }
367}
368
369impl From<io::Error> for PersyError {
370    fn from(err: io::Error) -> Self {
371        #[cfg(feature = "test_backtraces")]
372        eprintln!("{:?}", backtrace::Backtrace::new());
373        PersyError::Io { from: err }
374    }
375}
376
377impl From<GenericError> for PersyError {
378    fn from(e: GenericError) -> Self {
379        match e {
380            GenericError::Io { from } => PersyError::Io { from },
381            GenericError::DecodingUtf8(e) => PersyError::DecodingUtf8(e),
382            GenericError::VarIntError(e) => PersyError::VarIntError(e),
383        }
384    }
385}
386
387impl From<CreateSegmentError> for PersyError {
388    fn from(e: CreateSegmentError) -> Self {
389        match e {
390            CreateSegmentError::Generic(e) => e.into(),
391            CreateSegmentError::SegmentAlreadyExists => PersyError::SegmentAlreadyExists,
392        }
393    }
394}
395
396#[derive(Debug, Error)]
397#[non_exhaustive]
398pub enum DeleteError {
399    #[error(transparent)]
400    Generic(#[from] GenericError),
401    #[error("The id '{0}' has no valid format")]
402    RecordNotFound(PersyId),
403    #[error("Segment Not Found")]
404    SegmentNotFound,
405    #[error("The id '{0}' has no valid format")]
406    InvalidPersyId(RecRef),
407}
408
409impl From<ReadError> for DeleteError {
410    fn from(e: ReadError) -> Self {
411        match e {
412            ReadError::Generic(e) => e.into(),
413            ReadError::SegmentNotFound => DeleteError::SegmentNotFound,
414            ReadError::InvalidPersyId(id) => DeleteError::InvalidPersyId(id),
415        }
416    }
417}
418impl From<SegmentError> for DeleteError {
419    fn from(e: SegmentError) -> Self {
420        match e {
421            SegmentError::Generic(e) => e.into(),
422            SegmentError::SegmentNotFound => DeleteError::SegmentNotFound,
423        }
424    }
425}
426
427impl From<DeleteError> for PersyError {
428    fn from(e: DeleteError) -> Self {
429        match e {
430            DeleteError::Generic(e) => e.into(),
431            DeleteError::RecordNotFound(id) => PersyError::RecordNotFound(id),
432            DeleteError::SegmentNotFound => PersyError::SegmentNotFound,
433            DeleteError::InvalidPersyId(id) => PersyError::InvalidPersyId(id),
434        }
435    }
436}
437
438#[derive(Debug, Error)]
439#[non_exhaustive]
440pub enum UpdateError {
441    #[error(transparent)]
442    Generic(#[from] GenericError),
443    #[error("The id '{0}' has no valid format")]
444    RecordNotFound(PersyId),
445    #[error("Segment Not Found")]
446    SegmentNotFound,
447    #[error("Size of the record is too big")]
448    RecordToBig,
449    #[error("The id '{0}' has no valid format")]
450    InvalidPersyId(RecRef),
451}
452
453impl From<SegmentError> for UpdateError {
454    fn from(e: SegmentError) -> Self {
455        match e {
456            SegmentError::Generic(e) => e.into(),
457            SegmentError::SegmentNotFound => UpdateError::SegmentNotFound,
458        }
459    }
460}
461
462impl From<ReadError> for UpdateError {
463    fn from(e: ReadError) -> Self {
464        match e {
465            ReadError::Generic(e) => e.into(),
466            ReadError::SegmentNotFound => UpdateError::SegmentNotFound,
467            ReadError::InvalidPersyId(id) => UpdateError::InvalidPersyId(id),
468        }
469    }
470}
471
472impl From<UpdateError> for PersyError {
473    fn from(e: UpdateError) -> Self {
474        match e {
475            UpdateError::Generic(e) => e.into(),
476            UpdateError::RecordToBig => PersyError::RecordToBig,
477            UpdateError::RecordNotFound(id) => PersyError::RecordNotFound(id),
478            UpdateError::SegmentNotFound => PersyError::SegmentNotFound,
479            UpdateError::InvalidPersyId(id) => PersyError::InvalidPersyId(id),
480        }
481    }
482}
483
484#[derive(Debug, Error)]
485#[non_exhaustive]
486pub enum IndexOpsError {
487    #[error(transparent)]
488    Generic(#[from] GenericError),
489    #[error("Index Not Found")]
490    IndexNotFound,
491    #[error("Index method type mismatch persistent types: {0}")]
492    IndexTypeMismatch(Cow<'static, str>),
493}
494
495impl From<IndexOpsError> for PersyError {
496    fn from(e: IndexOpsError) -> Self {
497        match e {
498            IndexOpsError::Generic(e) => e.into(),
499            IndexOpsError::IndexNotFound => PersyError::SegmentNotFound,
500            IndexOpsError::IndexTypeMismatch(s) => PersyError::IndexTypeMismatch(s),
501        }
502    }
503}
504
505impl From<IndexError> for IndexOpsError {
506    fn from(e: IndexError) -> Self {
507        match e {
508            IndexError::Generic(e) => IndexOpsError::Generic(e),
509            IndexError::IndexNotFound => IndexOpsError::IndexNotFound,
510        }
511    }
512}
513#[derive(Debug, Error)]
514#[non_exhaustive]
515pub enum PrepareError {
516    #[error(transparent)]
517    Generic(#[from] GenericError),
518    #[error("Index Not Found")]
519    IndexNotFound,
520    #[error("Segment Not Found")]
521    SegmentNotFound,
522    #[error("Segment Already Exists")]
523    SegmentAlreadyExists,
524    #[error("Index Already Exists")]
525    IndexAlreadyExists,
526    #[error("Timeout acquiring the data locks for the transaction")]
527    TransactionTimeout,
528    #[error("Record Not Found {0}")]
529    RecordNotFound(PersyId),
530    #[error("Version Not Latest")]
531    VersionNotLatest,
532    #[error("Reached the limit of retry changing the index")]
533    ReachedLimitOfRetry,
534    #[error("Found duplicate key:{0} for index: {1}")]
535    IndexDuplicateKey(String, String),
536}
537
538impl From<ReadError> for PrepareError {
539    fn from(read: ReadError) -> PrepareError {
540        match read {
541            ReadError::Generic(e) => PrepareError::Generic(e),
542            ReadError::SegmentNotFound => PrepareError::SegmentNotFound,
543            ReadError::InvalidPersyId(_) => panic!("Invalid id should have failed before"),
544        }
545    }
546}
547
548impl From<TimeoutError> for PrepareError {
549    fn from(e: TimeoutError) -> Self {
550        match e {
551            TimeoutError::LockTimeout => PrepareError::TransactionTimeout,
552        }
553    }
554}
555
556impl From<PrepareError> for PersyError {
557    fn from(e: PrepareError) -> Self {
558        match e {
559            PrepareError::Generic(ee) => ee.into(),
560            PrepareError::IndexNotFound => PersyError::IndexNotFound,
561            PrepareError::SegmentNotFound => PersyError::SegmentNotFound,
562            PrepareError::SegmentAlreadyExists => PersyError::SegmentAlreadyExists,
563            PrepareError::IndexAlreadyExists => PersyError::IndexAlreadyExists,
564            PrepareError::TransactionTimeout => PersyError::TransactionTimeout,
565            PrepareError::RecordNotFound(id) => PersyError::RecordNotFound(id),
566            PrepareError::VersionNotLatest => PersyError::VersionNotLatest,
567            PrepareError::ReachedLimitOfRetry => PersyError::ReachedLimitOfRetry,
568            PrepareError::IndexDuplicateKey(a, b) => PersyError::IndexDuplicateKey(a, b),
569        }
570    }
571}
572
573#[derive(Debug, Error)]
574pub enum TimeoutError {
575    #[error("Timeout acquiring the data locks")]
576    LockTimeout,
577}
578
579impl From<TimeoutError> for PersyError {
580    fn from(e: TimeoutError) -> Self {
581        match e {
582            TimeoutError::LockTimeout => PersyError::TransactionTimeout,
583        }
584    }
585}
586
587pub type PIRes<T> = Result<T, IndexChangeError>;
588
589#[derive(Debug, Error)]
590#[non_exhaustive]
591pub enum IndexChangeError {
592    #[error(transparent)]
593    Generic(#[from] GenericError),
594    #[error("Timeout acquiring the data locks")]
595    LockTimeout,
596    #[error("Reached the limit of retry changing the index")]
597    ReachedLimitOfRetry,
598    #[error("Index Not Found")]
599    IndexNotFound,
600    #[error("Index method type mismatch persistent types: {0}")]
601    IndexTypeMismatch(Cow<'static, str>),
602    #[error("Found duplicate key:{0} for index: {1}")]
603    IndexDuplicateKey(String, String),
604}
605
606impl From<TimeoutError> for IndexChangeError {
607    fn from(e: TimeoutError) -> Self {
608        match e {
609            TimeoutError::LockTimeout => IndexChangeError::LockTimeout,
610        }
611    }
612}
613
614impl From<IndexOpsError> for IndexChangeError {
615    fn from(e: IndexOpsError) -> Self {
616        match e {
617            IndexOpsError::Generic(ee) => IndexChangeError::Generic(ee),
618            IndexOpsError::IndexNotFound => IndexChangeError::IndexNotFound,
619            IndexOpsError::IndexTypeMismatch(s) => IndexChangeError::IndexTypeMismatch(s),
620        }
621    }
622}
623
624impl From<IndexError> for IndexChangeError {
625    fn from(e: IndexError) -> Self {
626        match e {
627            IndexError::Generic(ee) => IndexChangeError::Generic(ee),
628            IndexError::IndexNotFound => IndexChangeError::IndexNotFound,
629        }
630    }
631}
632
633impl From<SegmentError> for IndexChangeError {
634    fn from(e: SegmentError) -> Self {
635        match e {
636            SegmentError::Generic(ee) => IndexChangeError::Generic(ee),
637            SegmentError::SegmentNotFound => IndexChangeError::IndexNotFound,
638        }
639    }
640}
641
642impl From<DeleteError> for IndexChangeError {
643    fn from(e: DeleteError) -> Self {
644        match e {
645            DeleteError::Generic(ee) => IndexChangeError::Generic(ee),
646            DeleteError::SegmentNotFound => IndexChangeError::IndexNotFound,
647            DeleteError::RecordNotFound(_) => panic!("Record should be protected by lock while index update"),
648            DeleteError::InvalidPersyId(_) => panic!("Internally should never get and invalid id"),
649        }
650    }
651}
652
653impl From<UpdateError> for IndexChangeError {
654    fn from(e: UpdateError) -> Self {
655        match e {
656            UpdateError::Generic(ee) => IndexChangeError::Generic(ee),
657            UpdateError::SegmentNotFound => IndexChangeError::IndexNotFound,
658            UpdateError::RecordToBig => panic!("Record size should be limited by key sizes"),
659            UpdateError::RecordNotFound(_) => panic!("Record should be protected by lock while index update"),
660            UpdateError::InvalidPersyId(_) => panic!("Internally should never get an invalid id"),
661        }
662    }
663}
664
665impl From<InsertError> for IndexChangeError {
666    fn from(e: InsertError) -> Self {
667        match e {
668            InsertError::Generic(ee) => IndexChangeError::Generic(ee),
669            InsertError::SegmentNotFound => IndexChangeError::IndexNotFound,
670            InsertError::RecordToBig => panic!("Record size should be limited by key sizes"),
671        }
672    }
673}
674
675impl From<IndexChangeError> for PrepareError {
676    fn from(e: IndexChangeError) -> Self {
677        match e {
678            IndexChangeError::Generic(ee) => PrepareError::Generic(ee),
679            IndexChangeError::IndexNotFound => PrepareError::IndexNotFound,
680            IndexChangeError::IndexTypeMismatch(_) => {
681                panic!("In the prepare context should not be there a index type miss match")
682            }
683            IndexChangeError::LockTimeout => PrepareError::TransactionTimeout,
684            IndexChangeError::ReachedLimitOfRetry => PrepareError::ReachedLimitOfRetry,
685            IndexChangeError::IndexDuplicateKey(a, b) => PrepareError::IndexDuplicateKey(a, b),
686        }
687    }
688}
689
690impl From<IndexChangeError> for PersyError {
691    fn from(e: IndexChangeError) -> Self {
692        match e {
693            IndexChangeError::Generic(ee) => ee.into(),
694            IndexChangeError::IndexNotFound => PersyError::IndexNotFound,
695            IndexChangeError::IndexTypeMismatch(i) => PersyError::IndexTypeMismatch(i),
696            IndexChangeError::LockTimeout => PersyError::TransactionTimeout,
697            IndexChangeError::ReachedLimitOfRetry => PersyError::ReachedLimitOfRetry,
698            IndexChangeError::IndexDuplicateKey(a, b) => PersyError::IndexDuplicateKey(a, b),
699        }
700    }
701}
702
703#[derive(Debug, Error)]
704#[non_exhaustive]
705pub enum IndexPutError {
706    #[error(transparent)]
707    Generic(#[from] GenericError),
708    #[error("Index Not Found")]
709    IndexNotFound,
710    #[error("Index method type mismatch persistent types: {0}")]
711    IndexTypeMismatch(Cow<'static, str>),
712    #[error("The key or the value are over the allowed size limit")]
713    KeyOrValueTooBig,
714}
715impl From<IndexOpsError> for IndexPutError {
716    fn from(e: IndexOpsError) -> Self {
717        match e {
718            IndexOpsError::Generic(ee) => Self::Generic(ee),
719            IndexOpsError::IndexNotFound => Self::IndexNotFound,
720            IndexOpsError::IndexTypeMismatch(s) => Self::IndexTypeMismatch(s),
721        }
722    }
723}
724
725impl From<IndexPutError> for PersyError {
726    fn from(e: IndexPutError) -> Self {
727        match e {
728            IndexPutError::Generic(ee) => ee.into(),
729            IndexPutError::IndexNotFound => Self::IndexNotFound,
730            IndexPutError::IndexTypeMismatch(i) => Self::IndexTypeMismatch(i),
731            IndexPutError::KeyOrValueTooBig => Self::KeyOrValueTooBig,
732        }
733    }
734}
735
736impl From<IndexError> for IndexPutError {
737    fn from(e: IndexError) -> Self {
738        match e {
739            IndexError::Generic(ee) => Self::Generic(ee),
740            IndexError::IndexNotFound => Self::IndexNotFound,
741        }
742    }
743}
744
745#[derive(Debug, Error)]
746#[non_exhaustive]
747pub enum InvalidPersyId {
748    #[error("String decoding error: {0}")]
749    DecodingUtf8(#[from] str::Utf8Error),
750    #[error("Failure acquiring lock for poisoning")]
751    DecodingDataEncoding(#[from] data_encoding::DecodeError),
752    #[error("The id '{0}' has no valid format")]
753    InvalidPersyId(String),
754}
755
756impl From<InvalidPersyId> for PersyError {
757    fn from(e: InvalidPersyId) -> Self {
758        match e {
759            InvalidPersyId::InvalidPersyId(id) => PersyError::InvalidId(id),
760            InvalidPersyId::DecodingUtf8(err) => PersyError::DecodingUtf8(err),
761            InvalidPersyId::DecodingDataEncoding(err) => PersyError::DecodingDataEncoding(err),
762        }
763    }
764}
765
766#[derive(Debug, Error)]
767#[non_exhaustive]
768pub enum OpenError {
769    #[error("Failure acquiring file lock: {0}")]
770    AlreadyInUse(io::Error),
771    #[error("File do not exists")]
772    NotExists,
773    #[error("Cannot create a new file already exists")]
774    AlreadyExists,
775    #[error("The file specified is not a Persy file")]
776    NotPersyFile,
777    #[error("{0}")]
778    InitError(String),
779    #[error(transparent)]
780    Generic(#[from] GenericError),
781}
782
783impl From<OpenError> for PersyError {
784    fn from(e: OpenError) -> Self {
785        match e {
786            OpenError::AlreadyInUse(err) => PersyError::AlreadyInUse(err),
787            OpenError::InitError(e) => PersyError::InitError(e),
788            OpenError::NotExists => PersyError::NotExists,
789            OpenError::AlreadyExists => PersyError::AlreadyExists,
790            OpenError::NotPersyFile => PersyError::NotPersyFile,
791            OpenError::Generic(ge) => ge.into(),
792        }
793    }
794}
795impl From<io::Error> for OpenError {
796    fn from(err: io::Error) -> Self {
797        if err.kind() == io::ErrorKind::NotFound {
798            OpenError::NotExists
799        } else if err.raw_os_error() == fs2::lock_contended_error().raw_os_error() {
800            OpenError::AlreadyInUse(err)
801        } else if err.kind() == io::ErrorKind::AlreadyExists {
802            OpenError::AlreadyExists
803        } else {
804            OpenError::from(GenericError::from(err))
805        }
806    }
807}
808
809impl From<CreateError> for OpenError {
810    fn from(e: CreateError) -> Self {
811        match e {
812            CreateError::AlreadyInUse(err) => OpenError::AlreadyInUse(err),
813            CreateError::AlreadyExists => OpenError::AlreadyExists,
814            CreateError::Generic(ge) => OpenError::Generic(ge),
815        }
816    }
817}
818
819#[derive(Debug, Error)]
820#[non_exhaustive]
821pub enum OpenMemoryError {
822    #[error("{0}")]
823    InitError(String),
824    #[error(transparent)]
825    Generic(#[from] GenericError),
826}
827
828impl From<OpenMemoryError> for PersyError {
829    fn from(e: OpenMemoryError) -> Self {
830        match e {
831            OpenMemoryError::InitError(e) => PersyError::InitError(e),
832            OpenMemoryError::Generic(ge) => ge.into(),
833        }
834    }
835}
836
837impl From<OpenError> for OpenMemoryError {
838    fn from(e: OpenError) -> Self {
839        match e {
840            OpenError::AlreadyInUse(_) => unreachable!(),
841            OpenError::InitError(ie) => OpenMemoryError::InitError(ie),
842            OpenError::NotExists => unreachable!(),
843            OpenError::AlreadyExists => unreachable!(),
844            OpenError::NotPersyFile => unreachable!(),
845            OpenError::Generic(ge) => OpenMemoryError::Generic(ge),
846        }
847    }
848}
849
850#[derive(Debug, Error)]
851#[non_exhaustive]
852pub enum CreateError {
853    #[error("Failure acquiring file lock: {0}")]
854    AlreadyInUse(io::Error),
855    #[error("Cannot create a new file already exists")]
856    AlreadyExists,
857    #[error(transparent)]
858    Generic(#[from] GenericError),
859}
860
861impl From<CreateError> for PersyError {
862    fn from(e: CreateError) -> Self {
863        match e {
864            CreateError::AlreadyInUse(err) => PersyError::AlreadyInUse(err),
865            CreateError::AlreadyExists => PersyError::AlreadyExists,
866            CreateError::Generic(ge) => ge.into(),
867        }
868    }
869}
870impl From<io::Error> for CreateError {
871    fn from(err: io::Error) -> Self {
872        if err.raw_os_error() == fs2::lock_contended_error().raw_os_error() {
873            CreateError::AlreadyInUse(err)
874        } else if err.kind() == io::ErrorKind::AlreadyExists {
875            CreateError::AlreadyExists
876        } else {
877            CreateError::from(GenericError::from(err))
878        }
879    }
880}
881
882impl From<OpenError> for CreateError {
883    fn from(open: OpenError) -> Self {
884        match open {
885            OpenError::Generic(g) => g.into(),
886            OpenError::NotExists => unreachable!(),
887            OpenError::InitError(_) => unreachable!(),
888            OpenError::AlreadyInUse(x) => CreateError::AlreadyInUse(x),
889            OpenError::NotPersyFile => unreachable!(),
890            OpenError::AlreadyExists => CreateError::AlreadyExists,
891        }
892    }
893}
894
895#[derive(Debug, Error)]
896#[non_exhaustive]
897pub enum InsertError {
898    #[error(transparent)]
899    Generic(#[from] GenericError),
900    #[error("Size of the record is too big")]
901    RecordToBig,
902    #[error("Segment Not Found")]
903    SegmentNotFound,
904}
905
906impl From<InsertError> for PersyError {
907    fn from(e: InsertError) -> Self {
908        match e {
909            InsertError::RecordToBig => PersyError::RecordToBig,
910            InsertError::Generic(ge) => ge.into(),
911            InsertError::SegmentNotFound => PersyError::SegmentNotFound,
912        }
913    }
914}
915
916impl From<SegmentError> for InsertError {
917    fn from(e: SegmentError) -> Self {
918        match e {
919            SegmentError::Generic(e) => InsertError::Generic(e),
920            SegmentError::SegmentNotFound => InsertError::SegmentNotFound,
921        }
922    }
923}