use crate::{
Error,
endpoint::OneDriveEndpoint,
list::{TreeItem, TreeItemKind, TreeItems, TreeList, join_path, strip_relative_path},
};
use chrono::DateTime;
use onedrive_api::{ItemLocation, resource::DriveItem};
use std::{
convert::{TryFrom, TryInto},
time::SystemTime,
};
const PATH_SEPARATOR: char = '/';
#[async_trait::async_trait]
impl TreeList for OneDriveEndpoint {
async fn list(&self, root_path: &str, prefix: Option<&str>) -> Result<TreeItems, Error> {
let path = Self::get_absolute_path(root_path, prefix, PATH_SEPARATOR);
let item_location = ItemLocation::from_path(&path).ok_or_else(|| {
Error::OneDrivePath(Self::get_absolute_path(root_path, prefix, PATH_SEPARATOR))
})?;
let drive = self.drive();
let children = drive.list_children(item_location).await?;
children
.iter()
.map(|drive_item| (drive_item, root_path, path.as_str()).try_into())
.collect()
}
}
impl TryFrom<(&DriveItem, &str, &str)> for TreeItem {
type Error = Error;
fn try_from(
(drive_item, root_path, total_path): (&DriveItem, &str, &str),
) -> Result<Self, Self::Error> {
let kind = match (&drive_item.folder, &drive_item.file, &drive_item.location) {
(Some(_), None, None) => TreeItemKind::Folder,
(None, Some(_), None) => TreeItemKind::File,
(None, None, Some(_)) => TreeItemKind::Link,
_ => return Err(Error::OneDriveItemKind),
};
let item_path = drive_item
.name
.as_ref()
.ok_or_else(|| Error::OneDriveItem("name".to_string()))?
.clone();
let path = join_path(total_path, &item_path, PATH_SEPARATOR);
let path = strip_relative_path(root_path, &path, PATH_SEPARATOR);
let size = drive_item
.size
.ok_or_else(|| Error::OneDriveItem("size".to_string()))? as u64;
let date_time_sting = drive_item
.last_modified_date_time
.as_ref()
.ok_or_else(|| Error::OneDriveItem("last modified date time".to_string()))?;
let datetime = DateTime::parse_from_rfc3339(date_time_sting)
.map_err(|error| Error::from((date_time_sting.as_str(), error)))?;
let last_update = SystemTime::from(datetime);
Ok(Self {
kind,
path,
root_path: root_path.to_string(),
size,
last_update,
mime_type: None,
separator: PATH_SEPARATOR,
})
}
}