From bda014971e3df9874b0b9cf5013d1fe41e945ded Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 11:37:07 -0300 Subject: [PATCH 1/8] Separate path operations --- ts-rs/src/export.rs | 100 +++++------------------------- ts-rs/src/export/path.rs | 2 + ts-rs/src/export/path/absolute.rs | 14 +++++ ts-rs/src/export/path/clean.rs | 33 ++++++++++ 4 files changed, 63 insertions(+), 86 deletions(-) create mode 100644 ts-rs/src/export/path.rs create mode 100644 ts-rs/src/export/path/absolute.rs create mode 100644 ts-rs/src/export/path/clean.rs diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index a0e699fe1..83b269266 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -10,6 +10,9 @@ use thiserror::Error; use ExportError::*; use crate::TS; +use path::{absolute::PathAbsolute, clean::PathClean}; + +mod path; const NOTE: &str = "// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.\n"; @@ -158,8 +161,7 @@ pub(crate) fn export_type_to_string() -> Result() -> Result { - let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").map_err(|_| ManifestDirNotSet)?; - let manifest_dir = Path::new(&manifest_dir); + let manifest_dir = Path::new(std::env!("CARGO_MANIFEST_DIR")); let path = PathBuf::from(T::get_export_to().ok_or(CannotBeExported(std::any::type_name::()))?); Ok(manifest_dir.join(path)) @@ -221,10 +223,6 @@ fn import_path(from: &Path, import: &Path) -> String { } } -fn to_absolute_path(path: &Path) -> Result { - Ok(std::env::current_dir()?.join(path).clean()) -} - // Construct a relative path from a provided base directory path to the provided path. // // Copyright 2012-2015 The Rust Project Developers. @@ -242,8 +240,9 @@ where P: AsRef, B: AsRef, { - let path = to_absolute_path(path.as_ref())?; - let base = to_absolute_path(base.as_ref())?; + use Component as C; + let path = path.as_ref().absolute().clean(); + let base = base.as_ref().absolute().clean(); let mut ita = path.components(); let mut itb = base.components(); @@ -251,8 +250,10 @@ where loop { match (ita.next(), itb.next()) { - (Some(Component::ParentDir), _) | (_, Some(Component::ParentDir)) => { - unreachable!("The paths have been cleaned, no parent dir components are present") + (Some(C::CurDir), _) | (_, Some(C::CurDir)) | (Some(C::ParentDir), _) | (_, Some(C::ParentDir)) => { + unreachable!( + "The paths are absolute and have been cleaned, no parent or current dir components are present" + ) }, (None, None) => break, (Some(a), None) => { @@ -260,13 +261,12 @@ where comps.extend(ita.by_ref()); break; } - (None, _) => comps.push(Component::ParentDir), + (None, _) => comps.push(C::ParentDir), (Some(a), Some(b)) if comps.is_empty() && a == b => (), - (Some(a), Some(Component::CurDir)) => comps.push(a), (Some(a), Some(_)) => { - comps.push(Component::ParentDir); + comps.push(C::ParentDir); for _ in itb { - comps.push(Component::ParentDir); + comps.push(C::ParentDir); } comps.push(a); comps.extend(ita.by_ref()); @@ -278,75 +278,3 @@ where Ok(comps.iter().map(|c| c.as_os_str()).collect()) } -// Copyright 2018 Dan Reeves -// Adapted from the `path-clean` crate -// https://github.com/danreeves/path-clean -trait PathClean: AsRef { - fn clean(&self) -> PathBuf { - clean(self) - } -} - -// Copyright 2018 Dan Reeves -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// Adapted from the `path-clean` crate -// https://github.com/danreeves/path-clean -impl PathClean for PathBuf {} - -// Copyright 2018 Dan Reeves -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// Adapted from the `path-clean` crate -// https://github.com/danreeves/path-clean -impl PathClean for Path {} - -// Copyright 2018 Dan Reeves -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// Copied verbatim from the `path-clean` crate -// https://github.com/danreeves/path-clean -pub fn clean

(path: P) -> PathBuf -where - P: AsRef, -{ - let mut out = Vec::new(); - - for comp in path.as_ref().components() { - match comp { - Component::CurDir => (), - Component::ParentDir => match out.last() { - Some(Component::RootDir) => (), - Some(Component::Normal(_)) => { - out.pop(); - } - None - | Some(Component::CurDir) - | Some(Component::ParentDir) - | Some(Component::Prefix(_)) => out.push(comp), - }, - comp => out.push(comp), - } - } - - if !out.is_empty() { - out.iter().collect() - } else { - PathBuf::from(".") - } -} diff --git a/ts-rs/src/export/path.rs b/ts-rs/src/export/path.rs new file mode 100644 index 000000000..6e8bb31f0 --- /dev/null +++ b/ts-rs/src/export/path.rs @@ -0,0 +1,2 @@ +pub mod absolute; +pub mod clean; diff --git a/ts-rs/src/export/path/absolute.rs b/ts-rs/src/export/path/absolute.rs new file mode 100644 index 000000000..8dfe33bfd --- /dev/null +++ b/ts-rs/src/export/path/absolute.rs @@ -0,0 +1,14 @@ +use std::{env, path::{Path, PathBuf}}; + +use super::clean::PathClean; + +/// This trait is responsible for converting a relative path +/// into an absolute path +pub trait PathAbsolute: AsRef + PathClean { + /// Converts a relative path into an absolute path. + fn absolute(&self) -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join(self).clean() + } +} + +impl + PathClean> PathAbsolute for T {} diff --git a/ts-rs/src/export/path/clean.rs b/ts-rs/src/export/path/clean.rs new file mode 100644 index 000000000..9d2d56b5a --- /dev/null +++ b/ts-rs/src/export/path/clean.rs @@ -0,0 +1,33 @@ +use std::path::{PathBuf, Path, Component}; + +pub trait PathClean: AsRef { + fn clean(&self) -> PathBuf { + let mut out = Vec::new(); + + for comp in self.as_ref().components() { + match comp { + Component::CurDir => (), + Component::ParentDir => match out.last() { + Some(Component::RootDir) => (), + Some(Component::Normal(_)) => { + out.pop(); + } + None + | Some(Component::CurDir) + | Some(Component::ParentDir) + | Some(Component::Prefix(_)) => out.push(comp), + }, + comp => out.push(comp), + } + } + + if !out.is_empty() { + out.iter().collect() + } else { + PathBuf::from(".") + } + } +} + +impl> PathClean for T {} + From 3157fe8c9e666e2fa17ab5589afa3aa8ed992e32 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 11:39:23 -0300 Subject: [PATCH 2/8] Simpify match --- ts-rs/src/export.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 83b269266..1976d88f1 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -250,7 +250,7 @@ where loop { match (ita.next(), itb.next()) { - (Some(C::CurDir), _) | (_, Some(C::CurDir)) | (Some(C::ParentDir), _) | (_, Some(C::ParentDir)) => { + (Some(C::CurDir | C::ParentDir), _) | (_, Some(C::CurDir | C::ParentDir)) => { unreachable!( "The paths are absolute and have been cleaned, no parent or current dir components are present" ) From bad0442cd45f095b9bee979e85d76ff06889a516 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 11:45:50 -0300 Subject: [PATCH 3/8] Remove extra call to clean --- ts-rs/src/export.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 1976d88f1..f310ca589 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -10,7 +10,7 @@ use thiserror::Error; use ExportError::*; use crate::TS; -use path::{absolute::PathAbsolute, clean::PathClean}; +use path::absolute::PathAbsolute; mod path; @@ -241,8 +241,8 @@ where B: AsRef, { use Component as C; - let path = path.as_ref().absolute().clean(); - let base = base.as_ref().absolute().clean(); + let path = path.as_ref().absolute(); + let base = base.as_ref().absolute(); let mut ita = path.components(); let mut itb = base.components(); From 4d9a6540f24bb86bebad7e0ddd54d797ba86a12d Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 11:55:41 -0300 Subject: [PATCH 4/8] Use absolute instead of manually joining path --- ts-rs/src/export.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index f310ca589..93e5babd4 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -7,7 +7,6 @@ use std::{ }; use thiserror::Error; -use ExportError::*; use crate::TS; use path::absolute::PathAbsolute; @@ -161,10 +160,13 @@ pub(crate) fn export_type_to_string() -> Result() -> Result { - let manifest_dir = Path::new(std::env!("CARGO_MANIFEST_DIR")); - let path = - PathBuf::from(T::get_export_to().ok_or(CannotBeExported(std::any::type_name::()))?); - Ok(manifest_dir.join(path)) + Ok( + Path::new( + &T::get_export_to() + .ok_or_else(|| std::any::type_name::()) + .map_err(ExportError::CannotBeExported)? + ).absolute() + ) } /// Push the declaration of `T` @@ -182,7 +184,7 @@ fn generate_decl(out: &mut String) { /// Push an import statement for all dependencies of `T` fn generate_imports(out: &mut String) -> Result<(), ExportError> { - let export_to = T::get_export_to().ok_or(CannotBeExported(std::any::type_name::()))?; + let export_to = T::get_export_to().ok_or(ExportError::CannotBeExported(std::any::type_name::()))?; let path = Path::new(&export_to); let deps = T::dependencies(); From 89c60c4aa245645608a45944379db5bafcab9822 Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 11:57:49 -0300 Subject: [PATCH 5/8] cargo fmt --- ts-rs/src/export.rs | 19 +++++++++---------- ts-rs/src/export/path/absolute.rs | 5 ++++- ts-rs/src/export/path/clean.rs | 3 +-- ts-rs/src/lib.rs | 10 ++-------- ts-rs/tests/path_bug.rs | 4 ++-- ts-rs/tests/struct_tag.rs | 1 - 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 93e5babd4..56c190ea6 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -6,10 +6,10 @@ use std::{ sync::{Mutex, OnceLock}, }; +use path::absolute::PathAbsolute; use thiserror::Error; use crate::TS; -use path::absolute::PathAbsolute; mod path; @@ -160,13 +160,12 @@ pub(crate) fn export_type_to_string() -> Result() -> Result { - Ok( - Path::new( - &T::get_export_to() - .ok_or_else(|| std::any::type_name::()) - .map_err(ExportError::CannotBeExported)? - ).absolute() + Ok(Path::new( + &T::get_export_to() + .ok_or_else(|| std::any::type_name::()) + .map_err(ExportError::CannotBeExported)?, ) + .absolute()) } /// Push the declaration of `T` @@ -184,7 +183,8 @@ fn generate_decl(out: &mut String) { /// Push an import statement for all dependencies of `T` fn generate_imports(out: &mut String) -> Result<(), ExportError> { - let export_to = T::get_export_to().ok_or(ExportError::CannotBeExported(std::any::type_name::()))?; + let export_to = + T::get_export_to().ok_or(ExportError::CannotBeExported(std::any::type_name::()))?; let path = Path::new(&export_to); let deps = T::dependencies(); @@ -256,7 +256,7 @@ where unreachable!( "The paths are absolute and have been cleaned, no parent or current dir components are present" ) - }, + } (None, None) => break, (Some(a), None) => { comps.push(a); @@ -279,4 +279,3 @@ where Ok(comps.iter().map(|c| c.as_os_str()).collect()) } - diff --git a/ts-rs/src/export/path/absolute.rs b/ts-rs/src/export/path/absolute.rs index 8dfe33bfd..6c915c901 100644 --- a/ts-rs/src/export/path/absolute.rs +++ b/ts-rs/src/export/path/absolute.rs @@ -1,4 +1,7 @@ -use std::{env, path::{Path, PathBuf}}; +use std::{ + env, + path::{Path, PathBuf}, +}; use super::clean::PathClean; diff --git a/ts-rs/src/export/path/clean.rs b/ts-rs/src/export/path/clean.rs index 9d2d56b5a..5690c71da 100644 --- a/ts-rs/src/export/path/clean.rs +++ b/ts-rs/src/export/path/clean.rs @@ -1,4 +1,4 @@ -use std::path::{PathBuf, Path, Component}; +use std::path::{Component, Path, PathBuf}; pub trait PathClean: AsRef { fn clean(&self) -> PathBuf { @@ -30,4 +30,3 @@ pub trait PathClean: AsRef { } impl> PathClean for T {} - diff --git a/ts-rs/src/lib.rs b/ts-rs/src/lib.rs index 2540d6204..4f99ed972 100644 --- a/ts-rs/src/lib.rs +++ b/ts-rs/src/lib.rs @@ -562,10 +562,7 @@ impl TS for Result { where Self: 'static, { - T::generics() - .push::() - .extend(E::generics()) - .push::() + T::generics().push::().extend(E::generics()).push::() } } @@ -658,10 +655,7 @@ impl TS for HashMap { where Self: 'static, { - K::generics() - .push::() - .extend(V::generics()) - .push::() + K::generics().push::().extend(V::generics()).push::() } } diff --git a/ts-rs/tests/path_bug.rs b/ts-rs/tests/path_bug.rs index a1cc6b1fc..f2ead2162 100644 --- a/ts-rs/tests/path_bug.rs +++ b/ts-rs/tests/path_bug.rs @@ -4,11 +4,11 @@ use ts_rs::TS; #[derive(TS)] #[ts(export, export_to = "../ts-rs/tests-out/path_bug/")] struct Foo { - bar: Bar + bar: Bar, } #[derive(TS)] #[ts(export_to = "tests-out/path_bug/aaa/")] struct Bar { - i: i32 + i: i32, } diff --git a/ts-rs/tests/struct_tag.rs b/ts-rs/tests/struct_tag.rs index 752a325f0..a1d8dd23d 100644 --- a/ts-rs/tests/struct_tag.rs +++ b/ts-rs/tests/struct_tag.rs @@ -20,4 +20,3 @@ fn test() { "{ type: \"TaggedType\", a: number, b: number, }" ) } - From a0e1c515025af4040d1f501a955b984b8e78bbdb Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 14:08:29 -0300 Subject: [PATCH 6/8] Fix compiler error --- ts-rs/src/export.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 56c190ea6..6e49562fa 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -110,7 +110,7 @@ pub(crate) fn export_type_to>( let fmt_cfg = ConfigurationBuilder::new().deno().build(); if let Some(formatted) = - format_text(path.as_ref(), &buffer, &fmt_cfg).map_err(|e| Formatting(e.to_string()))? + format_text(path.as_ref(), &buffer, &fmt_cfg).map_err(|e| ExportError::Formatting(e.to_string()))? { buffer = formatted; } From f73b809fcc71a91f330c7b1f04ff44302ad6365b Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 14:21:09 -0300 Subject: [PATCH 7/8] Change back to current_dir --- ts-rs/src/export.rs | 6 +++--- ts-rs/src/export/path/absolute.rs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 6e49562fa..5b5b17535 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -165,7 +165,7 @@ fn output_path() -> Result { .ok_or_else(|| std::any::type_name::()) .map_err(ExportError::CannotBeExported)?, ) - .absolute()) + .absolute()?) } /// Push the declaration of `T` @@ -243,8 +243,8 @@ where B: AsRef, { use Component as C; - let path = path.as_ref().absolute(); - let base = base.as_ref().absolute(); + let path = path.as_ref().absolute()?; + let base = base.as_ref().absolute()?; let mut ita = path.components(); let mut itb = base.components(); diff --git a/ts-rs/src/export/path/absolute.rs b/ts-rs/src/export/path/absolute.rs index 6c915c901..7dcb70526 100644 --- a/ts-rs/src/export/path/absolute.rs +++ b/ts-rs/src/export/path/absolute.rs @@ -1,6 +1,7 @@ use std::{ env, path::{Path, PathBuf}, + io::Result }; use super::clean::PathClean; @@ -9,8 +10,8 @@ use super::clean::PathClean; /// into an absolute path pub trait PathAbsolute: AsRef + PathClean { /// Converts a relative path into an absolute path. - fn absolute(&self) -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")).join(self).clean() + fn absolute(&self) -> Result { + Ok(Path::new(&env::current_dir()?).join(self).clean()) } } From b1c8485b9f0d070a0be912c7f18b4ba8056846bc Mon Sep 17 00:00:00 2001 From: Gustavo Date: Fri, 1 Mar 2024 14:26:25 -0300 Subject: [PATCH 8/8] cargo fmt --- ts-rs/src/export.rs | 4 ++-- ts-rs/src/export/path/absolute.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ts-rs/src/export.rs b/ts-rs/src/export.rs index 5b5b17535..b4ede7f2e 100644 --- a/ts-rs/src/export.rs +++ b/ts-rs/src/export.rs @@ -109,8 +109,8 @@ pub(crate) fn export_type_to>( use dprint_plugin_typescript::{configuration::ConfigurationBuilder, format_text}; let fmt_cfg = ConfigurationBuilder::new().deno().build(); - if let Some(formatted) = - format_text(path.as_ref(), &buffer, &fmt_cfg).map_err(|e| ExportError::Formatting(e.to_string()))? + if let Some(formatted) = format_text(path.as_ref(), &buffer, &fmt_cfg) + .map_err(|e| ExportError::Formatting(e.to_string()))? { buffer = formatted; } diff --git a/ts-rs/src/export/path/absolute.rs b/ts-rs/src/export/path/absolute.rs index 7dcb70526..94d7ebb1c 100644 --- a/ts-rs/src/export/path/absolute.rs +++ b/ts-rs/src/export/path/absolute.rs @@ -1,7 +1,7 @@ use std::{ env, + io::Result, path::{Path, PathBuf}, - io::Result }; use super::clean::PathClean;