blob: 94e9027e0107643bc1d9dbe33af410928503dba6 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(fxr/66157): Migrate to the new library that substitues io_utils and files_async.
// Ask for host-side support on the new library (fxr/467217).
use {
anyhow::{Error, Result},
fidl_fuchsia_io as fio,
files_async::*,
io_util::{directory::*, file::*},
};
#[cfg(target_os = "fuchsia")]
use std::path::PathBuf;
// A convenience wrapper over a FIDL FileProxy.
// Functions of this struct do not tolerate errors and will panic when they encounter them.
struct File {
proxy: fio::FileProxy,
}
impl File {
async fn read_string(&self) -> Result<String, Error> {
Ok(read_to_string(&self.proxy).await?)
}
async fn close(self) -> Result<(), Error> {
io_util::file::close(self.proxy).await?;
Ok(())
}
}
// A convenience wrapper over a FIDL DirectoryProxy.
// Functions of this struct do not tolerate errors and will panic when they encounter them.
pub struct Directory {
pub proxy: fio::DirectoryProxy,
}
impl Directory {
// Create a Directory object from a path in the namespace
#[cfg(target_os = "fuchsia")]
pub fn from_namespace(path: PathBuf) -> Result<Directory, Error> {
let path_str = path.into_os_string().into_string().expect("into_string() failed!");
let proxy = io_util::directory::open_in_namespace(
&path_str,
fio::OPEN_RIGHT_WRITABLE | fio::OPEN_RIGHT_READABLE,
)?;
Ok(Directory { proxy })
}
// Create a Directory object from a proxy
pub fn from_proxy(proxy: fio::DirectoryProxy) -> Directory {
Directory { proxy }
}
// Open a file that already exists in the directory with the given |filename|.
fn open_file(&self, filename: &str) -> Result<File, Error> {
let proxy = open_file_no_describe(&self.proxy, filename, fio::OPEN_RIGHT_READABLE)?;
Ok(File { proxy })
}
// Open a directory that already exists in the directory with the given |filename|.
pub fn open_dir(&self, filename: &str) -> Result<Directory, Error> {
let proxy = open_directory_no_describe(&self.proxy, filename, fio::OPEN_RIGHT_READABLE)?;
Ok(Directory { proxy })
}
// Returns the contents of a file in this directory as a string
pub async fn read_file(&self, filename: &str) -> Result<String, Error> {
let file = self.open_file(filename)?;
let data = file.read_string().await?;
file.close().await?;
Ok(data)
}
// Checks if a file exists in this directory.
// Function is not recursive. Does not check subdirectories.
pub async fn exists(&self, filename: &str) -> bool {
self.entries()
.await
.expect("Could not get entries from directory.")
.iter()
.any(|s| s == filename)
}
// Return a list of filenames in the directory
pub async fn entries(&self) -> Result<Vec<String>, Error> {
Ok(readdir(&self.proxy).await?.iter().map(|entry| entry.name.clone()).collect())
}
}