diff --git a/blobrepo/src/repo.rs b/blobrepo/src/repo.rs index a565f7c1ec..ba9491e40c 100644 --- a/blobrepo/src/repo.rs +++ b/blobrepo/src/repo.rs @@ -12,7 +12,6 @@ use std::thread; use std::time::Duration; use std::usize; -use ascii::AsciiString; use db::{get_connection_params, InstanceRequirement, ProxyRequirement}; use failure::{Fail, ResultExt}; use futures::{Async, Poll}; @@ -26,7 +25,7 @@ use time_ext::DurationExt; use uuid::Uuid; use blobstore::{Blobstore, CachingBlobstore}; -use bookmarks::{self, Bookmarks}; +use bookmarks::{self, Bookmark, BookmarkPrefix, Bookmarks}; use changesets::{CachingChangests, ChangesetInsert, Changesets, MysqlChangesets, SqliteChangesets}; use dbbookmarks::{MysqlDbBookmarks, SqliteDbBookmarks}; use delayblob::DelayBlob; @@ -299,7 +298,7 @@ impl BlobRepo { pub fn get_heads(&self) -> impl Stream { self.bookmarks - .list_by_prefix(&AsciiString::default(), &self.repoid) + .list_by_prefix(&BookmarkPrefix::empty(), &self.repoid) .map(|(_, cs)| cs.into_nodehash()) } @@ -348,14 +347,14 @@ impl BlobRepo { Box::new(HgBlobEntry::new_root(self.blobstore.clone(), *manifestid)) } - pub fn get_bookmark(&self, name: &AsciiString) -> BoxFuture, Error> { + pub fn get_bookmark(&self, name: &Bookmark) -> BoxFuture, Error> { self.bookmarks.get(name, &self.repoid) } // TODO(stash): rename to get_all_bookmarks()? - pub fn get_bookmarks(&self) -> BoxStream<(AsciiString, DChangesetId), Error> { - let empty_prefix = AsciiString::new(); - self.bookmarks.list_by_prefix(&empty_prefix, &self.repoid) + pub fn get_bookmarks(&self) -> BoxStream<(Bookmark, DChangesetId), Error> { + self.bookmarks + .list_by_prefix(&BookmarkPrefix::empty(), &self.repoid) } pub fn update_bookmark_transaction(&self) -> Box { diff --git a/bookmarks/dbbookmarks/src/lib.rs b/bookmarks/dbbookmarks/src/lib.rs index 46940edd5b..d181ccebf2 100644 --- a/bookmarks/dbbookmarks/src/lib.rs +++ b/bookmarks/dbbookmarks/src/lib.rs @@ -25,8 +25,7 @@ extern crate storage_types; mod schema; mod models; -use ascii::AsciiString; -use bookmarks::{Bookmarks, Transaction}; +use bookmarks::{Bookmark, BookmarkPrefix, Bookmarks, Transaction}; use diesel::{delete, insert_into, replace_into, update, MysqlConnection, SqliteConnection}; use diesel::connection::SimpleConnection; use diesel::prelude::*; @@ -136,16 +135,15 @@ macro_rules! impl_bookmarks { impl Bookmarks for $struct { fn get( &self, - name: &AsciiString, + name: &Bookmark, repo_id: &RepositoryId, ) -> BoxFuture, Error> { #[allow(unreachable_code, unreachable_patterns)] // sqlite can't fail let connection = try_boxfuture!(self.get_conn()); - let name = name.as_str().to_string(); schema::bookmarks::table .filter(schema::bookmarks::repo_id.eq(repo_id)) - .filter(schema::bookmarks::name.eq(name)) + .filter(schema::bookmarks::name.eq(name.to_string())) .select(schema::bookmarks::changeset_id) .first::(&*connection) .optional() @@ -156,9 +154,9 @@ macro_rules! impl_bookmarks { fn list_by_prefix( &self, - prefix: &AsciiString, + prefix: &BookmarkPrefix, repo_id: &RepositoryId, - ) -> BoxStream<(AsciiString, DChangesetId), Error> { + ) -> BoxStream<(Bookmark, DChangesetId), Error> { #[allow(unreachable_code, unreachable_patterns)] // sqlite can't fail let connection = match self.get_conn() { Ok(conn) => conn, @@ -167,10 +165,9 @@ macro_rules! impl_bookmarks { }, }; - let prefix = prefix.as_str().to_string(); let query = schema::bookmarks::table .filter(schema::bookmarks::repo_id.eq(repo_id)) - .filter(schema::bookmarks::name.like(format!("{}%", prefix))); + .filter(schema::bookmarks::name.like(format!("{}%", prefix.to_string()))); query .get_results::(&*connection) @@ -183,7 +180,7 @@ macro_rules! impl_bookmarks { }) .from_err() .flatten_stream() - .and_then(|entry| Ok((AsciiString::from_ascii(entry.0)?, entry.1))) + .and_then(|entry| Ok((Bookmark::new(entry.0)?, entry.1))) .boxify() } @@ -197,11 +194,11 @@ macro_rules! impl_bookmarks { struct $transaction_struct { db: $struct, - force_sets: HashMap, - creates: HashMap, - sets: HashMap, - force_deletes: HashSet, - deletes: HashMap, + force_sets: HashMap, + creates: HashMap, + sets: HashMap, + force_deletes: HashSet, + deletes: HashMap, repo_id: RepositoryId, } @@ -218,7 +215,7 @@ macro_rules! impl_bookmarks { } } - fn check_if_bookmark_already_used(&self, key: &AsciiString) -> Result<()> { + fn check_if_bookmark_already_used(&self, key: &Bookmark) -> Result<()> { if self.creates.contains_key(key) || self.force_sets.contains_key(key) || self.sets.contains_key(key) || self.force_deletes.contains(key) || self.deletes.contains_key(key) @@ -232,7 +229,7 @@ macro_rules! impl_bookmarks { impl Transaction for $transaction_struct { fn update( &mut self, - key: &AsciiString, + key: &Bookmark, new_cs: &DChangesetId, old_cs: &DChangesetId, ) -> Result<()> { @@ -247,25 +244,25 @@ macro_rules! impl_bookmarks { Ok(()) } - fn create(&mut self, key: &AsciiString, new_cs: &DChangesetId) -> Result<()> { + fn create(&mut self, key: &Bookmark, new_cs: &DChangesetId) -> Result<()> { self.check_if_bookmark_already_used(key)?; self.creates.insert(key.clone(), *new_cs); Ok(()) } - fn force_set(&mut self, key: &AsciiString, new_cs: &DChangesetId) -> Result<()> { + fn force_set(&mut self, key: &Bookmark, new_cs: &DChangesetId) -> Result<()> { self.check_if_bookmark_already_used(key)?; self.force_sets.insert(key.clone(), *new_cs); Ok(()) } - fn delete(&mut self, key: &AsciiString, old_cs: &DChangesetId) -> Result<()> { + fn delete(&mut self, key: &Bookmark, old_cs: &DChangesetId) -> Result<()> { self.check_if_bookmark_already_used(key)?; self.deletes.insert(key.clone(), *old_cs); Ok(()) } - fn force_delete(&mut self, key: &AsciiString) -> Result<()> { + fn force_delete(&mut self, key: &Bookmark) -> Result<()> { self.check_if_bookmark_already_used(key)?; self.force_deletes.insert(key.clone()); Ok(()) @@ -285,7 +282,7 @@ macro_rules! impl_bookmarks { .execute(&*connection)?; for (key, &BookmarkSetData { new_cs, old_cs }) in self.sets.iter() { - let key = key.as_str().to_string(); + let key = key.to_string(); let num_affected_rows = update( schema::bookmarks::table .filter(schema::bookmarks::name.eq(key.clone())) @@ -298,13 +295,13 @@ macro_rules! impl_bookmarks { } for key in self.force_deletes.iter() { - let key = key.as_str().to_string(); + let key = key.to_string(); delete(schema::bookmarks::table.filter(schema::bookmarks::name.eq(key))) .execute(&*connection)?; } for (key, old_cs) in self.deletes.iter() { - let key = key.as_str().to_string(); + let key = key.to_string(); let num_deleted_rows = delete( schema::bookmarks::table .filter(schema::bookmarks::name.eq(key.clone())) @@ -332,12 +329,12 @@ struct BookmarkSetData { fn create_bookmarks_rows( repo_id: RepositoryId, - map: &HashMap, + map: &HashMap, ) -> Vec { map.iter() .map(|(name, changeset_id)| models::BookmarkRow { repo_id, - name: name.as_str().to_string(), + name: name.to_string(), changeset_id: *changeset_id, }) .collect() diff --git a/bookmarks/dbbookmarks/tests/main.rs b/bookmarks/dbbookmarks/tests/main.rs index 0fcc00f986..0370f41a0d 100644 --- a/bookmarks/dbbookmarks/tests/main.rs +++ b/bookmarks/dbbookmarks/tests/main.rs @@ -20,11 +20,19 @@ extern crate mercurial_types; extern crate mercurial_types_mocks; extern crate tokio; -use ascii::AsciiString; +use bookmarks::{Bookmark, BookmarkPrefix}; use dbbookmarks::{MysqlDbBookmarks, SqliteDbBookmarks}; use mercurial_types_mocks::nodehash::{ONES_CSID, TWOS_CSID}; use mercurial_types_mocks::repo::REPO_ZERO; +fn create_bookmark(book: &str) -> Bookmark { + Bookmark::new(book.to_string()).unwrap() +} + +fn create_prefix(book: &str) -> BookmarkPrefix { + BookmarkPrefix::new(book.to_string()).unwrap() +} + macro_rules! bookmarks_test_impl { ($mod_name: ident => { new: $new_cb: expr, @@ -39,8 +47,8 @@ macro_rules! bookmarks_test_impl { #[test] fn test_simple_unconditional_set_get() { let bookmarks = $new_cb(); - let name_correct = AsciiString::from_ascii("book".to_string()).unwrap(); - let name_incorrect = AsciiString::from_ascii("book2".to_string()).unwrap(); + let name_correct = create_bookmark("book"); + let name_incorrect = create_bookmark("book2"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.force_set(&name_correct, &ONES_CSID).unwrap(); @@ -59,8 +67,8 @@ macro_rules! bookmarks_test_impl { #[test] fn test_multi_unconditional_set_get() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); - let name_2 = AsciiString::from_ascii("book2".to_string()).unwrap(); + let name_1 = create_bookmark("book"); + let name_2 = create_bookmark("book2"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.force_set(&name_1, &ONES_CSID).unwrap(); @@ -80,7 +88,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_unconditional_set_same_bookmark() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.force_set(&name_1, &ONES_CSID).unwrap(); @@ -99,7 +107,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_simple_create() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -114,7 +122,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_create_already_existing() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -128,7 +136,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_create_change_same_bookmark() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -166,7 +174,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_simple_update_bookmark() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -185,7 +193,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_update_non_existent_bookmark() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.update(&name_1, &TWOS_CSID, &ONES_CSID).unwrap(); @@ -195,7 +203,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_update_existing_bookmark_with_incorrect_commit() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -209,7 +217,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_force_delete() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.force_delete(&name_1).unwrap(); @@ -232,7 +240,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_delete() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.delete(&name_1, &ONES_CSID).unwrap(); @@ -251,7 +259,7 @@ macro_rules! bookmarks_test_impl { #[test] fn test_delete_incorrect_hash() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book".to_string()).unwrap(); + let name_1 = create_bookmark("book"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); @@ -266,15 +274,17 @@ macro_rules! bookmarks_test_impl { #[test] fn test_list_by_prefix() { let bookmarks = $new_cb(); - let name_1 = AsciiString::from_ascii("book1".to_string()).unwrap(); - let name_2 = AsciiString::from_ascii("book2".to_string()).unwrap(); + let name_1 = create_bookmark("book1"); + let name_2 = create_bookmark("book2"); let mut txn = bookmarks.create_transaction(&REPO_ZERO); txn.create(&name_1, &ONES_CSID).unwrap(); txn.create(&name_2, &ONES_CSID).unwrap(); txn.commit().wait().unwrap(); - let prefix = AsciiString::from_ascii("book".to_string()).unwrap(); + let prefix = create_prefix("book"); + let name_1_prefix = create_prefix("book1"); + let name_2_prefix = create_prefix("book2"); assert_eq!( bookmarks .list_by_prefix(&prefix, &REPO_ZERO) @@ -286,7 +296,7 @@ macro_rules! bookmarks_test_impl { assert_eq!( bookmarks - .list_by_prefix(&name_1, &REPO_ZERO) + .list_by_prefix(&name_1_prefix, &REPO_ZERO) .collect() .wait() .unwrap(), @@ -295,7 +305,7 @@ macro_rules! bookmarks_test_impl { assert_eq!( bookmarks - .list_by_prefix(&name_2, &REPO_ZERO) + .list_by_prefix(&name_2_prefix, &REPO_ZERO) .collect() .wait() .unwrap(), diff --git a/bookmarks/src/lib.rs b/bookmarks/src/lib.rs index 6b2f32035b..0cc600532a 100644 --- a/bookmarks/src/lib.rs +++ b/bookmarks/src/lib.rs @@ -7,22 +7,92 @@ #![deny(warnings)] extern crate ascii; +#[macro_use] extern crate failure_ext as failure; extern crate futures_ext; extern crate mercurial_types; +use std::fmt; + use ascii::AsciiString; use failure::{Error, Result}; use futures_ext::{BoxFuture, BoxStream}; use mercurial_types::{DChangesetId, RepositoryId}; +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Bookmark { + bookmark: AsciiString, +} + +impl fmt::Display for Bookmark { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.bookmark) + } +} + +impl Bookmark { + pub fn new>(bookmark: B) -> Result { + Ok(Self { + bookmark: AsciiString::from_ascii(bookmark.as_ref()) + .map_err(|bytes| format_err!("non-ascii bookmark name: {:?}", bytes))?, + }) + } + + pub fn new_ascii(bookmark: AsciiString) -> Self { + Self { bookmark } + } + + pub fn to_ascii(&self) -> Result { + Ok(self.bookmark.clone()) + } + + pub fn to_string(&self) -> String { + self.bookmark.clone().into() + } +} + +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct BookmarkPrefix { + bookmark_prefix: AsciiString, +} + +impl fmt::Display for BookmarkPrefix { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.bookmark_prefix) + } +} + +impl BookmarkPrefix { + pub fn new>(bookmark_prefix: B) -> Result { + Ok(Self { + bookmark_prefix: AsciiString::from_ascii(bookmark_prefix.as_ref()) + .map_err(|bytes| format_err!("non-ascii bookmark prefix: {:?}", bytes))?, + }) + } + + pub fn new_ascii(bookmark_prefix: AsciiString) -> Self { + Self { bookmark_prefix } + } + + pub fn empty() -> Self { + Self { + bookmark_prefix: AsciiString::default(), + } + } + + pub fn to_ascii(&self) -> Result { + Ok(self.bookmark_prefix.clone()) + } + + pub fn to_string(&self) -> String { + self.bookmark_prefix.clone().into() + } +} + pub trait Bookmarks: Send + Sync + 'static { /// Returns Some(DChangesetId) if bookmark exists, returns None if doesn't - fn get( - &self, - name: &AsciiString, - repoid: &RepositoryId, - ) -> BoxFuture, Error>; + fn get(&self, name: &Bookmark, repoid: &RepositoryId) + -> BoxFuture, Error>; /// Lists the bookmarks that match the prefix with bookmark's values. /// Empty prefix means list all of the available bookmarks @@ -30,9 +100,9 @@ pub trait Bookmarks: Send + Sync + 'static { /// listing all the bookmarks? fn list_by_prefix( &self, - prefix: &AsciiString, + prefix: &BookmarkPrefix, repoid: &RepositoryId, - ) -> BoxStream<(AsciiString, DChangesetId), Error>; + ) -> BoxStream<(Bookmark, DChangesetId), Error>; /// Creates a transaction that will be used for write operations. fn create_transaction(&self, repoid: &RepositoryId) -> Box; @@ -44,7 +114,7 @@ pub trait Transaction: Send + Sync + 'static { /// committing the transaction will fail. fn update( &mut self, - key: &AsciiString, + key: &Bookmark, new_cs: &DChangesetId, old_cs: &DChangesetId, ) -> Result<()>; @@ -52,20 +122,20 @@ pub trait Transaction: Send + Sync + 'static { /// Adds create() operation to the transaction set. /// Creates a bookmark. Bookmark should not already exist, otherwise committing the /// transaction will fail. - fn create(&mut self, key: &AsciiString, new_cs: &DChangesetId) -> Result<()>; + fn create(&mut self, key: &Bookmark, new_cs: &DChangesetId) -> Result<()>; /// Adds force_set() operation to the transaction set. /// Unconditionally sets the new value of the bookmark. Succeeds regardless of whether bookmark /// exists or not. - fn force_set(&mut self, key: &AsciiString, new_cs: &DChangesetId) -> Result<()>; + fn force_set(&mut self, key: &Bookmark, new_cs: &DChangesetId) -> Result<()>; /// Adds delete operation to the transaction set. /// Deletes bookmark only if it currently points to `old_cs`. - fn delete(&mut self, key: &AsciiString, old_cs: &DChangesetId) -> Result<()>; + fn delete(&mut self, key: &Bookmark, old_cs: &DChangesetId) -> Result<()>; /// Adds force_delete operation to the transaction set. /// Deletes bookmark unconditionally. - fn force_delete(&mut self, key: &AsciiString) -> Result<()>; + fn force_delete(&mut self, key: &Bookmark) -> Result<()>; /// Commits the transaction. Future succeeds if transaction has been /// successful, or errors if transaction has failed. Transaction may fail because of the diff --git a/bundle2-resolver/src/resolver.rs b/bundle2-resolver/src/resolver.rs index 659c6d164a..5fd8f197cb 100644 --- a/bundle2-resolver/src/resolver.rs +++ b/bundle2-resolver/src/resolver.rs @@ -131,7 +131,7 @@ struct ChangegroupPush { struct BookmarkPush { part_id: PartId, - name: AsciiString, + name: bookmarks::Bookmark, old: Option, new: Option, } @@ -241,6 +241,7 @@ impl Bundle2Resolver { ); let name = try_boxfuture!(get_ascii_param(mparams, "key")); + let name = bookmarks::Bookmark::new_ascii(name); let old = try_boxfuture!(get_optional_changeset_param(mparams, "old")); let new = try_boxfuture!(get_optional_changeset_param(mparams, "new")); diff --git a/cmds/new_blobimport/bookmark.rs b/cmds/new_blobimport/bookmark.rs index 876d2303ea..25643a80e4 100644 --- a/cmds/new_blobimport/bookmark.rs +++ b/cmds/new_blobimport/bookmark.rs @@ -13,6 +13,7 @@ use futures_ext::{BoxFuture, FutureExt}; use slog::Logger; use blobrepo::BlobRepo; +use bookmarks::Bookmark; use mercurial::RevlogRepo; use mercurial_types::DChangesetId; @@ -40,7 +41,7 @@ pub fn upload_bookmarks( let mut transaction = blobrepo.update_bookmark_transaction(); for (key, value) in vec { - let key = try_boxfuture!(AsciiString::from_ascii(key)); + let key = Bookmark::new_ascii(try_boxfuture!(AsciiString::from_ascii(key))); let value = DChangesetId::new(value.into_nodehash().into_mononoke()); try_boxfuture!(transaction.create(&key, &value)) } diff --git a/cmds/new_blobimport/main.rs b/cmds/new_blobimport/main.rs index 93dfbce248..4a263a2d0a 100644 --- a/cmds/new_blobimport/main.rs +++ b/cmds/new_blobimport/main.rs @@ -9,6 +9,7 @@ extern crate ascii; extern crate blobrepo; +extern crate bookmarks; extern crate bytes; extern crate changesets; extern crate clap; diff --git a/server/src/main.rs b/server/src/main.rs index cde9f6d2fd..bd05e759dd 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -8,7 +8,7 @@ #![feature(never_type)] #![feature(try_from)] -extern crate ascii; +extern crate bookmarks; #[macro_use] extern crate failure_ext as failure; #[macro_use] @@ -75,8 +75,6 @@ use std::sync::{Arc, Mutex}; use std::thread::{self, JoinHandle}; use std::time::Instant; -use ascii::AsciiString; - use failure::SlogKVError; use futures::{Future, IntoFuture, Sink, Stream}; use futures::sink::Wait; @@ -222,7 +220,7 @@ fn get_config<'a>(logger: &Logger, matches: &ArgMatches<'a>) -> Result { - let book = AsciiString::from_ascii(book).expect("book must be ascii"); + let book = bookmarks::Bookmark::new(book).expect("book must be ascii"); config_repo .get_bookmark(&book) .wait()? diff --git a/server/src/repo.rs b/server/src/repo.rs index cbda1ca59c..5d011cbfed 100644 --- a/server/src/repo.rs +++ b/server/src/repo.rs @@ -418,7 +418,7 @@ impl RepoClient { let blobrepo = self.repo.blobrepo.clone(); let items = blobrepo.get_bookmarks().map(|(name, cs)| { let hash: Vec = cs.into_nodehash().into_mercurial().to_hex().into(); - (name, hash) + (name.to_string(), hash) }); bundle.add_part(parts::listkey_part("bookmarks", items)?); } @@ -704,8 +704,7 @@ impl HgCommands for RepoClient { .collect() .map(|bookmarks| { let bookiter = bookmarks.into_iter().map(|(name, value)| { - let name: &[u8] = name.as_ref(); - (Vec::from(name), value) + (Vec::from(name.to_string()), value) }); HashMap::from_iter(bookiter) }) diff --git a/tests/fixtures/generate_memblob_repo.py b/tests/fixtures/generate_memblob_repo.py index 3390944900..81a4603711 100755 --- a/tests/fixtures/generate_memblob_repo.py +++ b/tests/fixtures/generate_memblob_repo.py @@ -58,7 +58,8 @@ extern crate slog; use std::str::FromStr; -use bookmarks::Bookmarks; +use ascii::AsciiString; +use bookmarks::{Bookmark, Bookmarks}; use changesets::{Changesets, ChangesetInsert, SqliteChangesets}; use memblob::EagerMemblob; use dbbookmarks::SqliteDbBookmarks; @@ -66,7 +67,6 @@ use dieselfilenodes::SqliteFilenodes; use mercurial_types::{DChangesetId, DNodeHash, RepositoryId}; use mononoke_types::BlobstoreBytes; use blobrepo::BlobRepo; -use ascii::AsciiString; use blobstore::Blobstore; use futures::future::Future; use slog::{Discard, Drain, Logger}; @@ -140,7 +140,7 @@ pub fn getrepo(logger: Option) -> BlobRepo { head = head[-40:] writeline( '''book_txn.create( - &AsciiString::from_ascii("head-{0}").unwrap(), + &Bookmark::new("head-{0}".to_string()).unwrap(), &DChangesetId::new(DNodeHash::from_ascii_str( &AsciiString::from_ascii("{0}").unwrap(), ).unwrap()),