diff --git a/rust/hg-core/src/revlog/changelog.rs b/rust/hg-core/src/revlog/changelog.rs --- a/rust/hg-core/src/revlog/changelog.rs +++ b/rust/hg-core/src/revlog/changelog.rs @@ -7,6 +7,7 @@ use crate::utils::hg_path::HgPath; use itertools::Itertools; use std::ascii::escape_default; +use std::borrow::Cow; use std::fmt::{Debug, Formatter}; /// A specialized `Revlog` to work with `changelog` data format. @@ -52,7 +53,7 @@ &self, rev: Revision, ) -> Result { - let bytes = self.revlog.get_rev_data(rev)?.into_owned(); + let bytes = self.revlog.get_rev_data(rev)?; if bytes.is_empty() { Ok(ChangelogRevisionData::null()) } else { @@ -79,9 +80,9 @@ /// `Changelog` entry which knows how to interpret the `changelog` data bytes. #[derive(PartialEq)] -pub struct ChangelogRevisionData { +pub struct ChangelogRevisionData<'changelog> { /// The data bytes of the `changelog` entry. - bytes: Vec, + bytes: Cow<'changelog, [u8]>, /// The end offset for the hex manifest (not including the newline) manifest_end: usize, /// The end offset for the user+email (not including the newline) @@ -93,8 +94,8 @@ files_end: usize, } -impl ChangelogRevisionData { - fn new(bytes: Vec) -> Result { +impl<'changelog> ChangelogRevisionData<'changelog> { + fn new(bytes: Cow<'changelog, [u8]>) -> Result { let mut line_iter = bytes.split(|b| b == &b'\n'); let manifest_end = line_iter .next() @@ -137,9 +138,9 @@ } fn null() -> Self { - Self::new( - b"0000000000000000000000000000000000000000\n\n0 0\n\n".to_vec(), - ) + Self::new(Cow::Borrowed( + b"0000000000000000000000000000000000000000\n\n0 0\n\n", + )) .unwrap() } @@ -181,7 +182,7 @@ } } -impl Debug for ChangelogRevisionData { +impl Debug for ChangelogRevisionData<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ChangelogRevisionData") .field("bytes", &debug_bytes(&self.bytes)) @@ -228,28 +229,30 @@ #[test] fn test_create_changelogrevisiondata_invalid() { // Completely empty - assert!(ChangelogRevisionData::new(b"abcd".to_vec()).is_err()); + assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd")).is_err()); // No newline after manifest - assert!(ChangelogRevisionData::new(b"abcd".to_vec()).is_err()); + assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd")).is_err()); // No newline after user - assert!(ChangelogRevisionData::new(b"abcd\n".to_vec()).is_err()); + assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd\n")).is_err()); // No newline after timestamp - assert!(ChangelogRevisionData::new(b"abcd\n\n0 0".to_vec()).is_err()); + assert!( + ChangelogRevisionData::new(Cow::Borrowed(b"abcd\n\n0 0")).is_err() + ); // Missing newline after files - assert!(ChangelogRevisionData::new( - b"abcd\n\n0 0\nfile1\nfile2".to_vec() - ) + assert!(ChangelogRevisionData::new(Cow::Borrowed( + b"abcd\n\n0 0\nfile1\nfile2" + )) .is_err(),); // Only one newline after files - assert!(ChangelogRevisionData::new( - b"abcd\n\n0 0\nfile1\nfile2\n".to_vec() - ) + assert!(ChangelogRevisionData::new(Cow::Borrowed( + b"abcd\n\n0 0\nfile1\nfile2\n" + )) .is_err(),); } #[test] fn test_create_changelogrevisiondata() { - let data = ChangelogRevisionData::new( + let data = ChangelogRevisionData::new(Cow::Borrowed( b"0123456789abcdef0123456789abcdef01234567 Some One 0 0 @@ -258,9 +261,8 @@ some commit -message" - .to_vec(), - ) +message", + )) .unwrap(); assert_eq!( data.manifest_node().unwrap(),