-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative handling of output paths #256
Conversation
|
||
/// Returns the output path to where `T` should be exported. | ||
/// | ||
/// When deriving `TS`, the output path can be altered using `#[ts(export_to = "...")]`. | ||
/// See the documentation of [`TS`] for more details. | ||
/// | ||
/// The output of this function depends on the environment variable `TS_RS_EXPORT_DIR`, which is | ||
/// used as base directory. If it is not set, `./bindings` is used as default directory. | ||
/// | ||
/// If `T` cannot be exported (e.g because it's a primitive type), this function will return | ||
/// `None`. | ||
fn output_path() -> Option<PathBuf> { | ||
None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the implementation: I moved output_path()
into TS
, and completely got rid of the const EXPORT_TO
.
fn output_path() -> Option<std::path::PathBuf> { | ||
let path = std::env::var("TS_RS_EXPORT_DIR"); | ||
let path = path.as_deref().unwrap_or("./bindings"); | ||
|
||
Some(std::path::Path::new(path).join(#path)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of that is super simple - Take TS_RS_EXPORT_DIR
(or ./bindings
), and append the name (or #[ts(export_to = "...")]
override to it.
In our example,
With
With this change, you'd get
|
#[derive(Serialize, TS)] | ||
#[ts(rename_all = "lowercase")] | ||
#[ts(export, export_to = "bindings/UserRole.ts")] | ||
#[ts(export, export_to = "UserRole.ts")] | ||
enum Role { | ||
User, | ||
#[ts(rename = "administrator")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before, renaming the file from Role.ts
to UserRole.ts
required adding the bindings/
prefix back again.
With this change, this is no longer necessary.
Oof, this |
Very nice way of dealing with it! |
Alright, then I'll go ahead and merge this! |
We could make a separate PR to remove |
Hey @escritorio-gustavo!
This is an experiment to see if we can further simplify and streamline the handling of export paths.
Let's start with a practical example:
Example
Before
In the workspace E2E test, there's the
parent
crate, which depends oncrate1
.The struct
crate1::Crate1
has#[ts(export_to = "crate1/")]
, andthe struct
parent::Parent
has#[ts(export)]
.When running
cargo test
, onlyparent::Parent
exports, but it takes its dependencycrate1::Crate1
with it.That results in this directory structure:
After
With this change, the resulting directory structure looks like this:
Explanation
Before
For a type, the output path is
./{TS_RS_EXPORT_DIR}/bindings/{name}.ts
if#[ts(export_to = "...")]
is not specified and./{TS_RS_EXPORT_DIR}/{name}.ts
if#[ts(export_to = "...")]
is specified.This is because
TS::EXPORT_TO
defaults tobindings/{name.ts}
, but changing it using#[ts(export_to = "...")]
gets rid of thebindings/
prefix.The environment variable
TS_RS_EXPORT_DIR
defaults to.
.After
With this change, it's the environment variable
TS_RS_EXPORT_DIR
which defaults to./bindings
.Therefore, with this change, the output path is always
./{TS_RS_EXPORT_DIR}/{name}.ts
.We take the
TS_RS_EXPORT_DIR
(or./bindings
), append the name to it (or the#[ts(export_to = "...")]
override), and we're done.I feel like this behaviour better matches what users would expect. They specify where there files should go relative to some base directory,
TS_RS_EXPORT_DIR
.What do you think?