Merge pull request #142 from erickt/role

Role can be inferred from the metadata
diff --git a/src/client.rs b/src/client.rs
index cbe1548..e014b92 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -28,7 +28,8 @@
 //!         .map(|k| KeyId::from_string(k).unwrap())
 //!         .collect();
 //!
-//!     let local = FileSystemRepository::<Json>::new(PathBuf::from("~/.rustup"));
+//!     let local = FileSystemRepository::<Json>::new(PathBuf::from("~/.rustup"))
+//!         .unwrap();
 //!
 //!     let remote = HttpRepository::new(
 //!         Url::parse("https://static.rust-lang.org/").unwrap(),
@@ -131,10 +132,7 @@
     ///
     /// **WARNING**: This method offers weaker security guarantees than the related method
     /// `with_root_pinned`.
-    pub fn new(config: Config<T>, mut local: L, mut remote: R) -> Result<Self> {
-        local.initialize()?;
-        remote.initialize()?;
-
+    pub fn new(config: Config<T>, mut local: L, remote: R) -> Result<Self> {
         let root = local
             .fetch_metadata(
                 &MetadataPath::from_role(&Role::Root),
@@ -177,9 +175,6 @@
         I: IntoIterator<Item = &'a KeyId>,
         T: PathTranslator,
     {
-        local.initialize()?;
-        remote.initialize()?;
-
         let root = local
             .fetch_metadata(
                 &MetadataPath::from_role(&Role::Root),
diff --git a/src/repository.rs b/src/repository.rs
index 9ee082d..c6649c6 100644
--- a/src/repository.rs
+++ b/src/repository.rs
@@ -28,9 +28,6 @@
     /// The type returned when reading a target.
     type TargetRead: Read;
 
-    /// Initialize the repository.
-    fn initialize(&mut self) -> Result<()>;
-
     /// Store signed metadata.
     ///
     /// Note: This **MUST** canonicalize the bytes before storing them as a read will expect the
@@ -98,11 +95,17 @@
     D: DataInterchange,
 {
     /// Create a new repository on the local file system.
-    pub fn new(local_path: PathBuf) -> Self {
-        FileSystemRepository {
+    pub fn new(local_path: PathBuf) -> Result<Self> {
+        for p in &["metadata", "targets", "temp"] {
+            DirBuilder::new().recursive(true).create(
+                local_path.join(p),
+            )?
+        }
+
+        Ok(FileSystemRepository {
             local_path,
             interchange: PhantomData,
-        }
+        })
     }
 }
 
@@ -112,16 +115,6 @@
 {
     type TargetRead = File;
 
-    fn initialize(&mut self) -> Result<()> {
-        for p in &["metadata", "targets", "temp"] {
-            DirBuilder::new().recursive(true).create(
-                self.local_path.join(p),
-            )?
-        }
-
-        Ok(())
-    }
-
     fn store_metadata<M>(
         &mut self,
         meta_path: &MetadataPath,
@@ -319,10 +312,6 @@
 {
     type TargetRead = Response;
 
-    fn initialize(&mut self) -> Result<()> {
-        Ok(())
-    }
-
     /// This always returns `Err` as storing over HTTP is not yet supported.
     fn store_metadata<M>(
         &mut self,
@@ -432,10 +421,6 @@
 {
     type TargetRead = Cursor<Vec<u8>>;
 
-    fn initialize(&mut self) -> Result<()> {
-        Ok(())
-    }
-
     fn store_metadata<M>(
         &mut self,
         meta_path: &MetadataPath,
@@ -524,7 +509,6 @@
     #[test]
     fn ephemeral_repo_targets() {
         let mut repo = EphemeralRepository::<Json>::new();
-        repo.initialize().unwrap();
 
         let data: &[u8] = b"like tears in the rain";
         let target_description = TargetDescription::from_reader(data, &[HashAlgorithm::Sha256])
@@ -546,8 +530,7 @@
     #[test]
     fn file_system_repo_targets() {
         let temp_dir = TempDir::new("rust-tuf").unwrap();
-        let mut repo = FileSystemRepository::<Json>::new(temp_dir.path().to_path_buf());
-        repo.initialize().unwrap();
+        let mut repo = FileSystemRepository::<Json>::new(temp_dir.path().to_path_buf()).unwrap();
 
         // test that init worked
         assert!(temp_dir.path().join("metadata").exists());
@@ -561,10 +544,16 @@
         repo.store_target(data, &path).unwrap();
         assert!(temp_dir.path().join("targets").join("foo").join("bar").join("baz").exists());
 
-        let mut read = repo.fetch_target(&path, &target_description, 0).unwrap();
         let mut buf = Vec::new();
-        read.read_to_end(&mut buf).unwrap();
-        assert_eq!(buf.as_slice(), data);
+
+        // Enclose `fetch_target` in a scope to make sure the file is closed.
+        // This is needed for `tempfile` on Windows, which doesn't open the
+        // files in a mode that allows the file to be opened multiple times.
+        {
+            let mut read = repo.fetch_target(&path, &target_description, 0).unwrap();
+            read.read_to_end(&mut buf).unwrap();
+            assert_eq!(buf.as_slice(), data);
+        }
 
         let bad_data: &[u8] = b"you're in a desert";
         repo.store_target(bad_data, &path).unwrap();