rust/hg-core/src/revlog/changelog.rs
changeset 50445 841b13e6e84c
parent 50444 b5dd6d6d6fa6
child 50448 071a6c1d291e
equal deleted inserted replaced
50444:b5dd6d6d6fa6 50445:841b13e6e84c
     1 use crate::errors::HgError;
     1 use crate::errors::HgError;
     2 use crate::revlog::Revision;
       
     3 use crate::revlog::{Node, NodePrefix};
     2 use crate::revlog::{Node, NodePrefix};
       
     3 use crate::revlog::{Revision, NULL_REVISION};
     4 use crate::revlog::{Revlog, RevlogEntry, RevlogError};
     4 use crate::revlog::{Revlog, RevlogEntry, RevlogError};
     5 use crate::utils::hg_path::HgPath;
     5 use crate::utils::hg_path::HgPath;
     6 use crate::vfs::Vfs;
     6 use crate::vfs::Vfs;
     7 use itertools::Itertools;
     7 use itertools::Itertools;
     8 use std::ascii::escape_default;
     8 use std::ascii::escape_default;
    30     ) -> Result<ChangelogRevisionData, RevlogError> {
    30     ) -> Result<ChangelogRevisionData, RevlogError> {
    31         let rev = self.revlog.rev_from_node(node)?;
    31         let rev = self.revlog.rev_from_node(node)?;
    32         self.data_for_rev(rev)
    32         self.data_for_rev(rev)
    33     }
    33     }
    34 
    34 
    35     /// Return the `RevlogEntry` for the given revision number.
    35     /// Return the [`ChangelogEntry`] for the given revision number.
    36     pub fn entry_for_rev(
    36     pub fn entry_for_rev(
    37         &self,
    37         &self,
    38         rev: Revision,
    38         rev: Revision,
    39     ) -> Result<RevlogEntry, RevlogError> {
    39     ) -> Result<ChangelogEntry, RevlogError> {
    40         self.revlog.get_entry(rev)
    40         let revlog_entry = self.revlog.get_entry(rev)?;
       
    41         Ok(ChangelogEntry { revlog_entry })
    41     }
    42     }
    42 
    43 
    43     /// Return the [`ChangelogRevisionData`] for the given revision number.
    44     /// Return the [`ChangelogRevisionData`] for the given revision number.
       
    45     ///
       
    46     /// This is a useful shortcut in case the caller does not need the
       
    47     /// generic revlog information (parents, hashes etc). Otherwise
       
    48     /// consider taking a [`ChangelogEntry`] with
       
    49     /// [entry_for_rev](`Self::entry_for_rev`) and doing everything from there.
    44     pub fn data_for_rev(
    50     pub fn data_for_rev(
    45         &self,
    51         &self,
    46         rev: Revision,
    52         rev: Revision,
    47     ) -> Result<ChangelogRevisionData, RevlogError> {
    53     ) -> Result<ChangelogRevisionData, RevlogError> {
    48         let bytes = self.revlog.get_rev_data(rev)?;
    54         if rev == NULL_REVISION {
       
    55             return Ok(ChangelogRevisionData::null());
       
    56         }
       
    57         self.entry_for_rev(rev)?.data()
       
    58     }
       
    59 
       
    60     pub fn node_from_rev(&self, rev: Revision) -> Option<&Node> {
       
    61         self.revlog.node_from_rev(rev)
       
    62     }
       
    63 
       
    64     pub fn rev_from_node(
       
    65         &self,
       
    66         node: NodePrefix,
       
    67     ) -> Result<Revision, RevlogError> {
       
    68         self.revlog.rev_from_node(node)
       
    69     }
       
    70 }
       
    71 
       
    72 /// A specialized `RevlogEntry` for `changelog` data format
       
    73 ///
       
    74 /// This is a `RevlogEntry` with the added semantics that the associated
       
    75 /// data should meet the requirements for `changelog`, materialized by
       
    76 /// the fact that `data()` constructs a `ChangelogRevisionData`.
       
    77 /// In case that promise would be broken, the `data` method returns an error.
       
    78 #[derive(Clone)]
       
    79 pub struct ChangelogEntry<'changelog> {
       
    80     /// Same data, as a generic `RevlogEntry`.
       
    81     pub(crate) revlog_entry: RevlogEntry<'changelog>,
       
    82 }
       
    83 
       
    84 impl<'changelog> ChangelogEntry<'changelog> {
       
    85     pub fn data<'a>(
       
    86         &'a self,
       
    87     ) -> Result<ChangelogRevisionData<'changelog>, RevlogError> {
       
    88         let bytes = self.revlog_entry.data()?;
    49         if bytes.is_empty() {
    89         if bytes.is_empty() {
    50             Ok(ChangelogRevisionData::null())
    90             Ok(ChangelogRevisionData::null())
    51         } else {
    91         } else {
    52             Ok(ChangelogRevisionData::new(bytes).map_err(|err| {
    92             Ok(ChangelogRevisionData::new(bytes).map_err(|err| {
    53                 RevlogError::Other(HgError::CorruptedRepository(format!(
    93                 RevlogError::Other(HgError::CorruptedRepository(format!(
    54                     "Invalid changelog data for revision {}: {:?}",
    94                     "Invalid changelog data for revision {}: {:?}",
    55                     rev, err
    95                     self.revlog_entry.revision(),
       
    96                     err
    56                 )))
    97                 )))
    57             })?)
    98             })?)
    58         }
    99         }
    59     }
   100     }
    60 
   101 
    61     pub fn node_from_rev(&self, rev: Revision) -> Option<&Node> {
   102     /// Obtain a reference to the underlying `RevlogEntry`.
    62         self.revlog.node_from_rev(rev)
   103     ///
    63     }
   104     /// This allows the caller to access the information that is common
    64 
   105     /// to all revlog entries: revision number, node id, parent revisions etc.
    65     pub fn rev_from_node(
   106     pub fn as_revlog_entry(&self) -> &RevlogEntry {
    66         &self,
   107         &self.revlog_entry
    67         node: NodePrefix,
       
    68     ) -> Result<Revision, RevlogError> {
       
    69         self.revlog.rev_from_node(node)
       
    70     }
   108     }
    71 }
   109 }
    72 
   110 
    73 /// `Changelog` entry which knows how to interpret the `changelog` data bytes.
   111 /// `Changelog` entry which knows how to interpret the `changelog` data bytes.
    74 #[derive(PartialEq)]
   112 #[derive(PartialEq)]