Skip to content

Commit

Permalink
workaround unc path on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
ncloudioj committed Jun 14, 2018
1 parent e5320fe commit e469367
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ lazy_static = "1.0"
lmdb = "0.7"
ordered-float = "0.5"
uuid = "0.5"

serde = "1.0"
url = "1.7.0"

# Get rid of failure's dependency on backtrace. Eventually
# backtrace will move into Rust core, but we don't need it here.
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extern crate lmdb;
extern crate ordered_float;
extern crate serde; // So we can specify trait bounds. Everything else is bincode.
extern crate uuid;
extern crate url;

pub use lmdb::{
DatabaseFlags,
Expand Down
28 changes: 25 additions & 3 deletions src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ use std::collections::{
BTreeMap,
};

use std::io::{
self,
Error,
ErrorKind,
};

use std::collections::btree_map::{
Entry,
};
Expand All @@ -30,6 +36,8 @@ use std::sync::{
RwLock,
};

use url::Url;

use error::{
StoreError,
};
Expand All @@ -44,6 +52,20 @@ lazy_static! {
};
}

// Workaround the UNC path on Windows, see https://github.com/rust-lang/rust/issues/42869.
// Otherwise, `Env::from_env()` will panic with error_no(123).
fn canonicalize_path<'p, P>(path: P) -> io::Result<PathBuf>
where P: Into<&'p Path> {
let canonical = path.into().canonicalize()?;
if cfg!(target_os = "windows") {
let url = Url::from_file_path(&canonical)
.map_err(|_e| Error::new(ErrorKind::Other, "URL passing error"))?;
return url.to_file_path()
.map_err(|_e| Error::new(ErrorKind::Other, "path canonicalization error"));
}
Ok(canonical)
}

pub struct Manager {
environments: BTreeMap<PathBuf, Arc<RwLock<Rkv>>>,
}
Expand All @@ -62,15 +84,15 @@ impl Manager {
/// Return the open env at `path`, returning `None` if it has not already been opened.
pub fn get<'p, P>(&self, path: P) -> Result<Option<Arc<RwLock<Rkv>>>, ::std::io::Error>
where P: Into<&'p Path> {
let canonical = path.into().canonicalize()?;
let canonical = canonicalize_path(path)?;
Ok(self.environments.get(&canonical).cloned())
}

/// Return the open env at `path`, or create it by calling `f`.
pub fn get_or_create<'p, F, P>(&mut self, path: P, f: F) -> Result<Arc<RwLock<Rkv>>, StoreError>
where F: FnOnce(&Path) -> Result<Rkv, StoreError>,
P: Into<&'p Path> {
let canonical = path.into().canonicalize()?;
let canonical = canonicalize_path(path)?;
Ok(match self.environments.entry(canonical) {
Entry::Occupied(e) => e.get().clone(),
Entry::Vacant(e) => {
Expand All @@ -85,7 +107,7 @@ impl Manager {
pub fn get_or_create_with_capacity<'p, F, P>(&mut self, path: P, capacity: c_uint, f: F) -> Result<Arc<RwLock<Rkv>>, StoreError>
where F: FnOnce(&Path, c_uint) -> Result<Rkv, StoreError>,
P: Into<&'p Path> {
let canonical = path.into().canonicalize()?;
let canonical = canonicalize_path(path)?;
Ok(match self.environments.entry(canonical) {
Entry::Occupied(e) => e.get().clone(),
Entry::Vacant(e) => {
Expand Down

0 comments on commit e469367

Please sign in to comment.