Add relative local path ankers, when parsing servers

This commit is contained in:
Leonard Steppy 2025-02-03 00:29:23 +01:00
parent f2f7f3bae9
commit da2b6097e9
2 changed files with 31 additions and 14 deletions

View File

@ -10,7 +10,7 @@ use crate::command::{ExecutionError, LogRunnable, SpecificExecutionError};
use crate::file::{FileMatcher, FileNameInfo};
use crate::logger::{LogLevel, Logger};
use crate::os_string_builder::ReplaceWithOsStr;
use crate::server::ServerAddress;
use crate::server::{RelativeLocalPathAnker, ServerAddress};
use clap::{Parser, Subcommand, ValueEnum};
use lazy_regex::{lazy_regex, Lazy, Regex};
use server::{Server, ServerReference};
@ -614,7 +614,7 @@ fn parse_server_configuration(config_str: &str) -> Result<Vec<Server>, String> {
config_str
.split(',')
.map(|server_entry| {
Server::from_str(server_entry)
Server::from_str(server_entry, RelativeLocalPathAnker::Home)
.map_err(|e| format!("Invalid server entry '{server_entry}': {e}"))
})
.collect()

View File

@ -2,6 +2,7 @@ use crate::get_home_directory;
use std::cell::LazyCell;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::fs;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::path::PathBuf;
@ -71,7 +72,7 @@ impl FromStr for ServerReference {
type Err = ServerReferenceParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Server::from_str(s)
Server::from_str(s, RelativeLocalPathAnker::CurrentDirectory)
.map(Self::Resolved)
.or_else(|_| Ok(Self::Identifier(s.to_string())))
}
@ -124,22 +125,28 @@ impl Server {
ServerAddress::Localhost => "this computer",
}
}
}
impl FromStr for Server {
type Err = ServerParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
pub fn from_str(
s: &str,
relative_local_path_anker: RelativeLocalPathAnker,
) -> Result<Self, ServerParseError> {
s.split_once(':')
.ok_or(ServerParseError::MissingServerDirectory)
.and_then(|(identifier, server_directory)| {
let address = ServerAddress::from_str(identifier);
let mut server_directory_path = PathBuf::from(server_directory);
if let ServerAddress::Localhost = &address {
let home_directory = get_home_directory()
.map_err(|e| ServerParseError::HomeDirectoryRequired { detail_message: e })?;
server_directory_path = home_directory.join(&server_directory_path);
}
let server_directory_path = match &address {
ServerAddress::Ssh { .. } => PathBuf::from(server_directory),
ServerAddress::Localhost => fs::canonicalize(match relative_local_path_anker {
RelativeLocalPathAnker::Home => {
let home_directory = get_home_directory()
.map_err(|e| ServerParseError::HomeDirectoryRequired { detail_message: e })?;
home_directory.join(server_directory)
}
RelativeLocalPathAnker::CurrentDirectory => PathBuf::from(server_directory),
})
.map_err(|_| ServerParseError::ServerDirectoryNonExistent)?,
};
Ok(Self {
address,
server_directory_path,
@ -162,6 +169,12 @@ impl Display for Server {
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum RelativeLocalPathAnker {
Home,
CurrentDirectory,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum ServerAddress {
Ssh { ssh_address: String },
@ -201,6 +214,7 @@ impl ServerAddress {
#[derive(Debug)]
pub enum ServerParseError {
MissingServerDirectory,
ServerDirectoryNonExistent,
HomeDirectoryRequired { detail_message: String },
}
@ -218,6 +232,9 @@ impl Display for ServerParseError {
f,
"localhost requires home directory, but: {detail_message}"
),
ServerParseError::ServerDirectoryNonExistent => {
write!(f, "The specified server directory doesn't exist")
}
}
}
}