hermes-tdata 0.1.0

Pure Rust parser for Telegram Desktop's tdata storage format. Decrypts local storage and extracts auth keys without Qt/C++ dependencies.
Documentation
//! Error types for hermes-tdata

use std::path::PathBuf;

/// Result type alias for hermes-tdata operations
pub type Result<T> = std::result::Result<T, Error>;

/// Errors that can occur during tdata parsing
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// IO error while reading tdata files
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    /// The tdata folder path does not exist
    #[error("tdata folder not found: {path}")]
    FolderNotFound {
        /// Path that was not found
        path: PathBuf,
    },

    /// Required file is missing from tdata folder
    #[error("required file not found: {file} in {folder}")]
    FileNotFound {
        /// Name of the missing file
        file: String,
        /// Folder where file was expected
        folder: PathBuf,
    },

    /// Key file (`key_data`, `key_datas`) not found
    #[error("key file not found in tdata folder")]
    KeyFileNotFound,

    /// Failed to decrypt tdata - wrong passcode or corrupted data
    #[error("decryption failed: wrong passcode or corrupted data")]
    DecryptionFailed,

    /// The tdata folder is password-protected but no passcode provided
    #[error("tdata is password-protected, passcode required")]
    PasscodeRequired,

    /// Invalid passcode provided
    #[error("invalid passcode")]
    InvalidPasscode,

    /// `QDataStream` parsing error
    #[error("QDataStream parse error: {message}")]
    QDataStreamError {
        /// Error message describing the parse failure
        message: String,
    },

    /// Unexpected end of data while parsing
    #[error("unexpected end of data at offset {offset}")]
    UnexpectedEof {
        /// Byte offset where EOF was encountered
        offset: u64,
    },

    /// Invalid UTF-16 string data
    #[error("invalid UTF-16 string data")]
    InvalidUtf16,

    /// Invalid data format or structure
    #[error("invalid data format: {message}")]
    InvalidFormat {
        /// Description of the format violation
        message: String,
    },

    /// No accounts found in tdata
    #[error("no accounts found in tdata")]
    NoAccounts,

    /// Account index out of range
    #[error("account index {index} out of range (max: {max})")]
    AccountIndexOutOfRange {
        /// Requested account index
        index: usize,
        /// Maximum valid index
        max: usize,
    },

    /// MD5 checksum mismatch in encrypted data
    #[error("checksum mismatch: data may be corrupted")]
    ChecksumMismatch,

    /// Unsupported tdata version
    #[error("unsupported tdata version: {version}")]
    UnsupportedVersion {
        /// The unsupported version number
        version: u32,
    },

    /// Auth key extraction failed
    #[error("failed to extract auth key: {reason}")]
    AuthKeyExtractionFailed {
        /// Reason for extraction failure
        reason: String,
    },
}

impl Error {
    /// Create a `QDataStream` error with a message
    pub fn qdatastream(msg: impl Into<String>) -> Self {
        Self::QDataStreamError { message: msg.into() }
    }

    /// Create an invalid format error with a message
    pub fn invalid_format(msg: impl Into<String>) -> Self {
        Self::InvalidFormat { message: msg.into() }
    }

    /// Create an auth key extraction error
    pub fn auth_key_failed(reason: impl Into<String>) -> Self {
        Self::AuthKeyExtractionFailed { reason: reason.into() }
    }
}