manifest-tree: implement TryFrom for directly converting from a serialized manifest tree entry to a manifest::List

Summary: Allow `manifest-tree::Entry` to be constructed directly by other crates, and introduce a `TryFrom` conversion to `manifest::List::Directory`. This will be used by the scmstore `BackingStore` implementation to avoid having to rely on the `TreeStore` trait, which does not support batching.

Reviewed By: kulshrax

Differential Revision: D30282738

fbshipit-source-id: 590350dd53217fa8a181e91b194abca753a8adbe
This commit is contained in:
Meyer Jacobs 2021-08-12 19:33:46 -07:00 committed by Facebook GitHub Bot
parent 5048cf3e0f
commit 65bceaf5e5
2 changed files with 28 additions and 3 deletions

View File

@ -29,7 +29,10 @@ use pathmatcher::Matcher;
use types::{HgId, Key, PathComponent, PathComponentBuf, RepoPath, RepoPathBuf};
pub(crate) use self::link::Link;
pub use self::{diff::Diff, store::TreeStore};
pub use self::{
diff::Diff,
store::{Entry as TreeEntry, TreeStore},
};
use crate::{
iter::{BfsIter, DfsCursor, Step},
link::{DirLink, Durable, DurableEntry, Ephemeral, Leaf},

View File

@ -6,6 +6,7 @@
*/
use std::{
convert::TryFrom,
str::{from_utf8, FromStr},
sync::Arc,
};
@ -13,7 +14,7 @@ use std::{
use anyhow::{format_err, Result};
use bytes::{Bytes, BytesMut};
use manifest::FileType;
use manifest::{FileMetadata, FileType, FsNodeMetadata};
use types::{HgId, Key, PathComponent, PathComponentBuf, RepoPath};
/// The `TreeStore` is an abstraction layer for the tree manifest that decouples how or where the
@ -100,7 +101,7 @@ impl InnerStore {
/// representation. For this serialization format it is important that they don't contain
/// `\0` or `\n`.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Entry(Bytes);
pub struct Entry(pub Bytes);
pub struct EntryMut(BytesMut);
@ -200,6 +201,27 @@ impl<'a> Iterator for Elements<'a> {
}
}
impl TryFrom<Entry> for manifest::List {
type Error = anyhow::Error;
fn try_from(v: Entry) -> Result<Self> {
let mut entries = Vec::new();
for entry in v.elements() {
let entry = entry?;
entries.push((
entry.component,
match entry.flag {
Flag::Directory => FsNodeMetadata::Directory(Some(entry.hgid)),
Flag::File(file_type) => {
FsNodeMetadata::File(FileMetadata::new(entry.hgid, file_type))
}
},
))
}
Ok(manifest::List::Directory(entries))
}
}
impl Element {
pub fn new(component: PathComponentBuf, hgid: HgId, flag: Flag) -> Element {
Element {