From a1a210204bf6dda80e676275ef54409dc21eff4e Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sat, 25 Nov 2023 13:11:15 +0900 Subject: [PATCH 1/4] cursed --- crates/impls/Cargo.toml | 6 ++++++ crates/impls/build.rs | 27 +++++++++++++++++++++++++++ crates/impls/src/lib.rs | 3 +++ src/lib.rs | 4 ++++ 4 files changed, 40 insertions(+) create mode 100644 crates/impls/Cargo.toml create mode 100644 crates/impls/build.rs create mode 100644 crates/impls/src/lib.rs diff --git a/crates/impls/Cargo.toml b/crates/impls/Cargo.toml new file mode 100644 index 00000000..48e9d53a --- /dev/null +++ b/crates/impls/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "specta-impls" +version = "0.0.1" +edition = "2021" + +[dependencies] diff --git a/crates/impls/build.rs b/crates/impls/build.rs new file mode 100644 index 00000000..c1224032 --- /dev/null +++ b/crates/impls/build.rs @@ -0,0 +1,27 @@ +use std::{ + fs::{create_dir_all, File}, + io::Write, + path::PathBuf, +}; + +fn main() { + // TODO: Windows support + let path = PathBuf::from("/tmp") // std::env::var("CARGO_TARGET_DIR").unwrap()) + .join("_specta"); + create_dir_all(&path).ok(); + let mut file = File::create(path.join("impls.rs")).unwrap(); + file.write_all( + b"use crate::{Type, DataType, DefOpts}; + + impl Type for specta_impls::Testing { + fn inline(_: DefOpts, _: &[DataType]) -> DataType { + DataType::Any + } + }", + ) + .unwrap(); + + // println!("{:?}", std::env::var("OUT_DIR")); + // std::env::set_var("SPECTA_DEMO", "123"); + // println!("cargo:rustc-env=SPECTA_DEMO=123"); +} diff --git a/crates/impls/src/lib.rs b/crates/impls/src/lib.rs new file mode 100644 index 00000000..59fc8f4b --- /dev/null +++ b/crates/impls/src/lib.rs @@ -0,0 +1,3 @@ +//! TODO + +pub struct Testing(); diff --git a/src/lib.rs b/src/lib.rs index 7beef1db..c43b7612 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,10 @@ #[doc(hidden)] pub mod internal; +pub mod impls { + include!("/tmp/_specta/impls.rs"); +} + /// Types related to working with [`DataType`](crate::DataType). Exposed for advanced users. pub mod datatype; /// Provides the global type store and a method to export them to other languages. From bb85f1116ceaa662e080a8339a3b18c13150add5 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sat, 25 Nov 2023 13:11:29 +0900 Subject: [PATCH 2/4] also this --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index d8eb94e1..586a8387 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,7 @@ bevy_ecs = ["dep:bevy_ecs"] [dependencies] specta-macros = { version = "=2.0.0-rc.6", path = "./macros" } +specta-impls = { version = ">=0.0.0", path = "./crates/impls" } serde = { version = "1.0.183", optional = true, default-features = false, features = ["derive"] } serde_json = { version = "1.0.104", optional = true, default-features = false, features = ["std"] } serde_yaml = { version = "0.9.25", optional = true, default-features = false, features = [] } @@ -139,3 +140,6 @@ once_cell = "1.18.0" doc-comment = "0.3.3" serde = { version = "1.0.183", features = ["derive"] } trybuild = "1.0.82" + +[workspace] +members = ["./crates/impls"] From b3576942ae98de0b60c1a97d4ec041a32f87439a Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sat, 25 Nov 2023 13:15:07 +0900 Subject: [PATCH 3/4] i dislike this --- crates/impls/build.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/impls/build.rs b/crates/impls/build.rs index c1224032..a559045c 100644 --- a/crates/impls/build.rs +++ b/crates/impls/build.rs @@ -4,6 +4,10 @@ use std::{ path::PathBuf, }; +// TODO: Issues: +// - Can we make these `impls`'s show up in the docs??? +// - Can we avoid using a global directory. It should lock to the target dir so it's not gonna have race conditions. + fn main() { // TODO: Windows support let path = PathBuf::from("/tmp") // std::env::var("CARGO_TARGET_DIR").unwrap()) From c9c4b34072393a1f3af00a1b0ef18c43d00cbda6 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Sat, 25 Nov 2023 19:13:29 +0900 Subject: [PATCH 4/4] this shit is cursed but probs the way --- Cargo.toml | 1 + crates/impls/Cargo.toml | 4 ++++ crates/impls/build.rs | 31 ------------------------------- crates/impls/src/internal.rs | 35 +++++++++++++++++++++++++++++++++++ crates/impls/src/lib.rs | 17 ++++++++++++++++- examples/basic.rs | 3 +++ src/lib.rs | 3 ++- 7 files changed, 61 insertions(+), 33 deletions(-) delete mode 100644 crates/impls/build.rs create mode 100644 crates/impls/src/internal.rs diff --git a/Cargo.toml b/Cargo.toml index 586a8387..148065a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -140,6 +140,7 @@ once_cell = "1.18.0" doc-comment = "0.3.3" serde = { version = "1.0.183", features = ["derive"] } trybuild = "1.0.82" +specta-impls = { version = ">=0.0.0", path = "./crates/impls", features = ["testing"] } [workspace] members = ["./crates/impls"] diff --git a/crates/impls/Cargo.toml b/crates/impls/Cargo.toml index 48e9d53a..dd94d2dd 100644 --- a/crates/impls/Cargo.toml +++ b/crates/impls/Cargo.toml @@ -3,4 +3,8 @@ name = "specta-impls" version = "0.0.1" edition = "2021" +[features] +default = [] +testing = [] + [dependencies] diff --git a/crates/impls/build.rs b/crates/impls/build.rs deleted file mode 100644 index a559045c..00000000 --- a/crates/impls/build.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::{ - fs::{create_dir_all, File}, - io::Write, - path::PathBuf, -}; - -// TODO: Issues: -// - Can we make these `impls`'s show up in the docs??? -// - Can we avoid using a global directory. It should lock to the target dir so it's not gonna have race conditions. - -fn main() { - // TODO: Windows support - let path = PathBuf::from("/tmp") // std::env::var("CARGO_TARGET_DIR").unwrap()) - .join("_specta"); - create_dir_all(&path).ok(); - let mut file = File::create(path.join("impls.rs")).unwrap(); - file.write_all( - b"use crate::{Type, DataType, DefOpts}; - - impl Type for specta_impls::Testing { - fn inline(_: DefOpts, _: &[DataType]) -> DataType { - DataType::Any - } - }", - ) - .unwrap(); - - // println!("{:?}", std::env::var("OUT_DIR")); - // std::env::set_var("SPECTA_DEMO", "123"); - // println!("cargo:rustc-env=SPECTA_DEMO=123"); -} diff --git a/crates/impls/src/internal.rs b/crates/impls/src/internal.rs new file mode 100644 index 00000000..e9c2a766 --- /dev/null +++ b/crates/impls/src/internal.rs @@ -0,0 +1,35 @@ +//! The magic that makes this crate work. This module does *NOT* follow semver at all. + +// This macro must *NEVER* change signature, even in major releases!!!!! +// This is called by `specta` and `specta` depends on *any* version of this crate. +// +// This is a little hack to avoid the orphan rule. The code inside this is expanded inside `specta` so it can do `impl specta::Type for ...`. +#[macro_export] +macro_rules! impls { + // This runs in the context of the `specta` crate so the `cfg`'s won't work as expected. + () => { + use crate::{DataType, Type, TypeMap}; + + $crate::_feature_testing!(); + }; +} + +// TODO: Make a nicer abstraction for this + +#[macro_export] +#[cfg(any(feature = "testing", docsrs))] +macro_rules! _feature_testing { + () => { + impl Type for specta_impls::Testing { + fn inline(_: &mut TypeMap, _: &[DataType]) -> DataType { + DataType::Any + } + } + }; +} + +#[macro_export] +#[cfg(not(any(feature = "testing", docsrs)))] +macro_rules! _feature_testing { + () => {}; +} diff --git a/crates/impls/src/lib.rs b/crates/impls/src/lib.rs index 59fc8f4b..24c802d8 100644 --- a/crates/impls/src/lib.rs +++ b/crates/impls/src/lib.rs @@ -1,3 +1,18 @@ -//! TODO +//! # Specta Implementations +//! A collection of Specta integrations for popular crates. +//! +//! TODO: List of supported features, why this exists, semver rules +#![forbid(unsafe_code)] +#![warn(clippy::all, clippy::unwrap_used, clippy::panic)] // TODO: missing_docs +#![allow(clippy::module_inception)] +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc( + html_logo_url = "https://github.com/oscartbeaumont/specta/raw/main/.github/logo-128.png", + html_favicon_url = "https://github.com/oscartbeaumont/specta/raw/main/.github/logo-128.png" +)] +#[doc(hidden)] +mod internal; + +#[cfg(feature = "testing")] pub struct Testing(); diff --git a/examples/basic.rs b/examples/basic.rs index aabda69a..a98d61b7 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -62,4 +62,7 @@ fn main() { ts_str, r#"export type Something = { a: { [key in MyEnum]: number } }"#.to_string() ); + + let ts_str = ts::inline::(&ExportConfig::default()).unwrap(); + println!("{ts_str}"); } diff --git a/src/lib.rs b/src/lib.rs index c43b7612..2263c171 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,8 @@ pub mod internal; pub mod impls { - include!("/tmp/_specta/impls.rs"); + // TODO: Can we make these `impls`'s show up in the docs??? + specta_impls::impls!(); } /// Types related to working with [`DataType`](crate::DataType). Exposed for advanced users.