From 08b9bf99a5cf1b510f8d85fdc99c96711b8e6d2c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 5 Sep 2024 00:25:02 +0200 Subject: [PATCH] remove last std dependency --- src/dest.rs | 26 +++++++++----------------- src/filestore.rs | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/dest.rs b/src/dest.rs index 44d6933..1fe48fd 100644 --- a/src/dest.rs +++ b/src/dest.rs @@ -1,6 +1,5 @@ use crate::{user::TransactionFinishedParams, DummyPduProvider, GenericSendError, PduProvider}; use core::str::{from_utf8, from_utf8_unchecked, Utf8Error}; -use std::path::Path; use super::{ filestore::{FilestoreError, NativeFilestore, VirtualFilestore}, @@ -696,7 +695,6 @@ impl< &self.tparams.file_properties.dest_file_name [..self.tparams.file_properties.dest_file_name_len], )?; - //let dest_path = Path::new(dest_name); self.tparams.file_properties.dest_path_buf[0..dest_name.len()] .copy_from_slice(dest_name.as_bytes()); self.tparams.file_properties.dest_file_path_len = dest_name.len(); @@ -732,30 +730,20 @@ impl< cfdp_user.metadata_recvd_indication(&metadata_recvd_params); if self.vfs.exists(dest_name)? && self.vfs.is_dir(dest_name)? { - // TODO: We require a VFS function to retrieve the file name from a full path to - // avoid the last std runtime dependency. - // Create new destination path by concatenating the last part of the source source // name and the destination folder. For example, for a source file of /tmp/hello.txt // and a destination name of /home/test, the resulting file name should be // /home/test/hello.txt // Safety: It was already verified that the path is valid during the transaction start. - let source_path = Path::new(unsafe { - from_utf8_unchecked( - //from_utf8( - &self.tparams.file_properties.src_file_name - [..self.tparams.file_properties.src_file_name_len], - ) - }); - let source_name = source_path.file_name(); - if source_name.is_none() { + let source_file_name = self.vfs.file_name(src_name)?; + if source_file_name.is_none() { return Err(DestError::PathConcat); } - let source_name = source_name.unwrap(); + let source_name = source_file_name.unwrap(); self.tparams.file_properties.dest_path_buf[dest_name.len()] = b'/'; self.tparams.file_properties.dest_path_buf [dest_name.len() + 1..dest_name.len() + 1 + source_name.len()] - .copy_from_slice(source_name.as_encoded_bytes()); + .copy_from_slice(source_name.as_bytes()); self.tparams.file_properties.dest_file_path_len += 1 + source_name.len(); } let dest_path_str = from_utf8( @@ -909,7 +897,11 @@ mod tests { use core::{cell::Cell, sync::atomic::AtomicBool}; #[allow(unused_imports)] use std::println; - use std::{fs, path::PathBuf, string::String}; + use std::{ + fs, + path::{Path, PathBuf}, + string::String, + }; use alloc::{sync::Arc, vec::Vec}; use rand::Rng; diff --git a/src/filestore.rs b/src/filestore.rs index a6886a4..ed17812 100644 --- a/src/filestore.rs +++ b/src/filestore.rs @@ -9,6 +9,7 @@ use std::path::Path; pub use std_mod::*; #[derive(Debug, Clone)] +#[non_exhaustive] pub enum FilestoreError { FileDoesNotExist, FileAlreadyExists, @@ -22,6 +23,8 @@ pub enum FilestoreError { string: String, }, ChecksumTypeNotImplemented(ChecksumType), + Utf8Error, + Other, } impl From for FilestoreError { @@ -64,6 +67,12 @@ impl Display for FilestoreError { FilestoreError::ChecksumTypeNotImplemented(checksum_type) => { write!(f, "checksum {:?} not implemented", checksum_type) } + FilestoreError::Utf8Error => { + write!(f, "utf8 error") + } + FilestoreError::Other => { + write!(f, "some filestore error occured") + } } } } @@ -128,6 +137,8 @@ pub trait VirtualFilestore { fn exists(&self, path: &str) -> Result; + fn file_name<'a>(&self, full_path: &'a str) -> Result, FilestoreError>; + fn file_size(&self, path: &str) -> Result; /// This special function is the CFDP specific abstraction to calculate the checksum of a file. @@ -201,6 +212,17 @@ pub mod std_mod { Ok(()) } + fn file_name<'a>(&self, full_path: &'a str) -> Result, FilestoreError> { + if self.is_dir(full_path)? { + return Err(FilestoreError::IsNotFile); + } + let path = Path::new(full_path); + + path.file_name() + .map(|s| s.to_str()) + .ok_or(FilestoreError::Utf8Error) + } + fn truncate_file(&self, file_path: &str) -> Result<(), FilestoreError> { if !self.exists(file_path)? { return Err(FilestoreError::FileDoesNotExist);