1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/piot/blob-stream-rs
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */
#[derive(Debug)]
pub enum BlobError {
    InvalidChunkIndex(usize, usize),
    UnexpectedChunkSize(usize, usize, usize),
    OutOfBounds,
    RedundantSameContents(ChunkIndex),
    RedundantContentDiffers(ChunkIndex),
}

impl fmt::Display for BlobError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::InvalidChunkIndex(index, max) => {
                write!(f, "illegal chunk index: {index} (max: {max})")
            }
            Self::UnexpectedChunkSize(expected, found, id) => write!(
                f,
                "unexpected chunk size. expected {expected} but encountered {found} for chunk {id}"
            ),
            Self::OutOfBounds => write!(f, "calculated slice range is out of bounds"),
            Self::RedundantSameContents(chunk_index) => write!(f, "chunk {chunk_index} has already been received"),
            Self::RedundantContentDiffers(chunk_index) => write!(f, "chunk {chunk_index} has already been received, but now received different content for that chunk. this is serious"),
        }
    }
}

impl Error for BlobError {} // it implements Debug and Display

use crate::ChunkIndex;
use core::fmt;
use std::error::Error;
use std::io;

impl From<BlobError> for io::Error {
    fn from(err: BlobError) -> Self {
        match err {
            // Map your custom error to an appropriate io::Error kind
            BlobError::InvalidChunkIndex(_, _) => {
                Self::new(io::ErrorKind::InvalidInput, err.to_string())
            }
            BlobError::OutOfBounds => Self::new(io::ErrorKind::UnexpectedEof, err.to_string()),
            BlobError::RedundantSameContents(_) => {
                Self::new(io::ErrorKind::AlreadyExists, err.to_string())
            }
            BlobError::RedundantContentDiffers(_) | BlobError::UnexpectedChunkSize(_, _, _) => {
                Self::new(io::ErrorKind::InvalidData, err.to_string())
            }
        }
    }
}