debugdata.rs
103 lines
| 3.0 KiB
| application/rls-services+xml
|
RustLexer
Antoine Cezar
|
r46098 | // debugdata.rs | ||
// | ||||
// Copyright 2020 Antoine Cezar <antoine.cezar@octobus.net> | ||||
// | ||||
// This software may be used and distributed according to the terms of the | ||||
// GNU General Public License version 2 or any later version. | ||||
Simon Sapin
|
r46751 | use std::path::Path; | ||
Antoine Cezar
|
r46098 | use crate::revlog::revlog::{Revlog, RevlogError}; | ||
Simon Sapin
|
r46647 | use crate::revlog::NodePrefix; | ||
Antoine Cezar
|
r46098 | use crate::revlog::Revision; | ||
/// Kind of data to debug | ||||
#[derive(Debug, Copy, Clone)] | ||||
pub enum DebugDataKind { | ||||
Changelog, | ||||
Manifest, | ||||
} | ||||
/// Kind of error encountered by DebugData | ||||
#[derive(Debug)] | ||||
pub enum DebugDataErrorKind { | ||||
/// Error when reading a `revlog` file. | ||||
IoError(std::io::Error), | ||||
/// The revision has not been found. | ||||
InvalidRevision, | ||||
Simon Sapin
|
r46646 | /// Found more than one revision whose ID match the requested prefix | ||
AmbiguousPrefix, | ||||
Antoine Cezar
|
r46098 | /// A `revlog` file is corrupted. | ||
CorruptedRevlog, | ||||
/// The `revlog` format version is not supported. | ||||
UnsuportedRevlogVersion(u16), | ||||
/// The `revlog` data format is not supported. | ||||
UnknowRevlogDataFormat(u8), | ||||
} | ||||
/// A DebugData error | ||||
#[derive(Debug)] | ||||
pub struct DebugDataError { | ||||
/// Kind of error encountered by DebugData | ||||
pub kind: DebugDataErrorKind, | ||||
} | ||||
impl From<DebugDataErrorKind> for DebugDataError { | ||||
fn from(kind: DebugDataErrorKind) -> Self { | ||||
DebugDataError { kind } | ||||
} | ||||
} | ||||
impl From<std::io::Error> for DebugDataError { | ||||
fn from(err: std::io::Error) -> Self { | ||||
let kind = DebugDataErrorKind::IoError(err); | ||||
DebugDataError { kind } | ||||
} | ||||
} | ||||
impl From<RevlogError> for DebugDataError { | ||||
fn from(err: RevlogError) -> Self { | ||||
match err { | ||||
RevlogError::IoError(err) => DebugDataErrorKind::IoError(err), | ||||
RevlogError::UnsuportedVersion(version) => { | ||||
DebugDataErrorKind::UnsuportedRevlogVersion(version) | ||||
} | ||||
RevlogError::InvalidRevision => { | ||||
DebugDataErrorKind::InvalidRevision | ||||
} | ||||
Simon Sapin
|
r46646 | RevlogError::AmbiguousPrefix => { | ||
DebugDataErrorKind::AmbiguousPrefix | ||||
} | ||||
Antoine Cezar
|
r46098 | RevlogError::Corrupted => DebugDataErrorKind::CorruptedRevlog, | ||
RevlogError::UnknowDataFormat(format) => { | ||||
DebugDataErrorKind::UnknowRevlogDataFormat(format) | ||||
} | ||||
} | ||||
.into() | ||||
} | ||||
} | ||||
/// Dump the contents data of a revision. | ||||
Simon Sapin
|
r46751 | pub fn debug_data( | ||
root: &Path, | ||||
rev: &str, | ||||
Antoine Cezar
|
r46098 | kind: DebugDataKind, | ||
Simon Sapin
|
r46751 | ) -> Result<Vec<u8>, DebugDataError> { | ||
let index_file = match kind { | ||||
DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"), | ||||
DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"), | ||||
}; | ||||
let revlog = Revlog::open(&index_file, None)?; | ||||
Antoine Cezar
|
r46098 | |||
Simon Sapin
|
r46751 | let data = match rev.parse::<Revision>() { | ||
Ok(rev) => revlog.get_rev_data(rev)?, | ||||
_ => { | ||||
let node = NodePrefix::from_hex(&rev) | ||||
.map_err(|_| DebugDataErrorKind::InvalidRevision)?; | ||||
let rev = revlog.get_node_rev(node.borrow())?; | ||||
revlog.get_rev_data(rev)? | ||||
} | ||||
}; | ||||
Antoine cezar
|
r46417 | |||
Simon Sapin
|
r46751 | Ok(data) | ||
Antoine Cezar
|
r46098 | } | ||