use crate::domain::value_object::WorkspaceJson;
use regex::Regex;
use rusqlite::Row;
use urlencoding::decode;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WorkspaceLocation {
NotRecognize,
Local,
Remote,
}
impl WorkspaceLocation {
fn default() -> Self {
WorkspaceLocation::NotRecognize
}
}
impl From<&str> for WorkspaceLocation {
fn from(path: &str) -> Self {
if path.starts_with("file://") {
WorkspaceLocation::Local
} else if path.starts_with("vscode-remote://") {
WorkspaceLocation::Remote
} else {
WorkspaceLocation::default()
}
}
}
#[derive(Debug, Clone, Eq)]
pub struct Workspace {
pub path: String,
pub decode_path: String,
pub location_type: WorkspaceLocation,
pub title: String,
}
impl Hash for Workspace {
fn hash<H: Hasher>(&self, state: &mut H) {
self.path.hash(state);
}
}
impl Workspace {
#[allow(dead_code)]
pub fn new() -> Self {
Workspace {
path: String::new(),
decode_path: String::new(),
location_type: WorkspaceLocation::default(),
title: String::new(),
}
}
pub fn from_dbrow(row: &Row) -> Self {
let raw_path: String = row.get(0).expect("msg");
let decode_path = decode(raw_path.as_str()).expect("UTF-8").to_string();
Workspace {
path: raw_path.clone(),
decode_path: decode_path.clone(),
location_type: raw_path.as_str().into(),
title: decode_path
.split('/')
.collect::<Vec<&str>>()
.last()
.unwrap()
.to_string(),
}
}
#[cfg(target_os = "windows")]
pub fn strip_decode_path(&self) -> String {
let strip_uri_prefix = Regex::new(r"(file|vscode-remote):[/]+").unwrap();
strip_uri_prefix.replace(&self.decode_path, "").to_string()
}
#[cfg(target_os = "linux")]
pub fn strip_decode_path(&self) -> String {
let strip_uri_prefix = Regex::new(r"(file|vscode-remote):[/][/]").unwrap();
strip_uri_prefix.replace(&self.decode_path, "").to_string()
}
}
impl PartialEq for Workspace {
fn eq(&self, other: &Self) -> bool {
self.path == other.path
}
}
impl From<WorkspaceJson> for Workspace {
fn from(_wj: WorkspaceJson) -> Self {
let decode_folder_path = decode(_wj.folder.as_str()).expect("UTF-8").to_string();
let location = WorkspaceLocation::from(_wj.folder.as_str());
Workspace {
path: _wj.folder,
decode_path: decode_folder_path.clone(),
location_type: location,
title: decode_folder_path
.split('/')
.collect::<Vec<&str>>()
.last()
.unwrap()
.to_string(),
}
}
}
impl From<&str> for Workspace {
fn from(raw_path: &str) -> Self {
let decode_folder_path = decode(raw_path).expect("UTF-8").to_string();
let location = WorkspaceLocation::from(raw_path);
Workspace {
path: raw_path.to_string(),
decode_path: decode_folder_path.clone(),
location_type: location,
title: decode_folder_path
.split('/')
.collect::<Vec<&str>>()
.last()
.unwrap()
.to_string(),
}
}
}
#[cfg(test)]
mod test_entity_workspace {
use super::*;
#[test]
fn test_workspace_new_associate_function() {
let w: Workspace = Workspace::new();
assert_eq!(w.path, String::new());
assert_eq!(w.decode_path, String::new());
assert_eq!(w.location_type, WorkspaceLocation::default());
assert_eq!(w.title, String::new());
}
#[test]
fn test_workspace_init_from_dbrow() {}
#[test]
fn test_workspace_strip_decode_path_successfully() {
let w: Workspace = Workspace::from("file://中文/ファイル");
assert_eq!(String::from("中文/ファイル"), w.strip_decode_path());
}
#[test]
fn test_workspace_convert_from_workspacejson() {
let folder_path = String::from("file://a/b/c");
let wj = WorkspaceJson {
folder: folder_path.clone(),
};
let w: Workspace = wj.into();
assert_eq!(w.path, folder_path);
}
#[test]
fn test_workspace_convert_from_strref() {
let w: Workspace = "file://a/b/c/d.d.d/e".into();
assert_eq!(w.location_type, WorkspaceLocation::Local);
assert_eq!(w.path, String::from("file://a/b/c/d.d.d/e"));
assert_eq!(w.title, String::from("e"));
}
#[test]
fn test_workspace_string_formatable() {
format!("{:?}", Workspace::from(""));
}
#[test]
#[allow(clippy::redundant_clone)]
fn test_workspace_cloneable() {
let _ = Workspace::new().clone();
}
#[test]
fn test_workspace_eq() {
assert!(Workspace::new() == Workspace::new())
}
}
#[cfg(test)]
mod test_entity_workspacelocation {
use super::*;
#[test]
fn test_workspacelocation_default_associate_function() {
let w = WorkspaceLocation::default();
assert_eq!(w, WorkspaceLocation::NotRecognize);
}
#[test]
fn test_workspacelocation_convert_from_strref() {
let w1: WorkspaceLocation = "file://".into();
let w2: WorkspaceLocation = "vscode-remote://".into();
let w3: WorkspaceLocation = "not-in-the-if-else-branches".into();
assert_eq!(w1, WorkspaceLocation::Local);
assert_eq!(w2, WorkspaceLocation::Remote);
assert_eq!(w3, WorkspaceLocation::default());
}
#[test]
fn test_workspacelocation_string_formatable() {
format!("{:?}", WorkspaceLocation::default());
}
#[test]
#[allow(clippy::redundant_clone)]
fn test_workspacelocation_cloneable() {
let _ = WorkspaceLocation::default().clone();
}
#[test]
fn test_workspacelocation_eq() {
assert!(WorkspaceLocation::default() == WorkspaceLocation::default());
}
}