Skip to content
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

Const JSON does not compile #10

Open
code-mart opened this issue Dec 7, 2022 · 4 comments
Open

Const JSON does not compile #10

code-mart opened this issue Dec 7, 2022 · 4 comments

Comments

@code-mart
Copy link

The following example, found in test/const/rust.rs does not compile for me:

#[tsync]
const SERDE_JSON_2: serde_json::Value = json!({ "a": "b" });

I get this error, among others:

mutable references are not allowed in constants

From my understanding, the constructor for serde_json::Value is not const, so using json! macro to initialize a const macro is not possible. Is there some way to successfully compile the const JSON?

@AravindPrabhs
Copy link
Contributor

Ah I overlooked this completely since for my use case I actually had a #[cfg(false)] around the const I wanted to tsync. So the code never actually got compiled.
I don't think this would be possible with the current tsync implementation I think would have to be extended for expressions maybe (let).

@Wulf
Copy link
Owner

Wulf commented Jan 22, 2023

Thanks @code-mart for reporting this and @AravindPrabhs for the details. I've added a little comment in the README linking to this issue so others can be aware. We may need to remove this if it's not achievable.

image

Closing for now; please feel free to re-open.

@Wulf Wulf closed this as completed Jan 22, 2023
@code-mart
Copy link
Author

Thanks @Wulf , I achieved this in a different way in my project. In order to evaluate macros (including concatenation of static strings, which is a basic feature for string constants), tsync would need to be working with a compiled project, rather than working with the source code, like tsync does now. This is because there is not a good, stable way (that I have found) to evaluate macros before compilation.

Additionally, with tsync's approach of using attribute-like macros, #[tsync], I could not find an elegant way to run the tsync code as part of the compiled project, without, for example, adding a function call to main.

I ended up creating a separate "constant-definer" crate, where I could include the constants in my rust code, and I would run all my export!() function-like macros to export the constants to typescript. This is basically what it looks like:

// Declare a static string.
lazy_static! {
    static ref MY_STRING: String = "some_string".to_string();
    static ref CONCATENATED: String = format!("{}_is_concatenated", MY_STRING.as_str());
}

// Convert static string to a typescript declaration and write to file.
macro_rules! export {
    ($name:ident, $file:ident) => (
        write!($file, "export const {}: string = \"{}\";\n\n", stringify!($name), ($name).as_str());
    )
}


pub fn export_all() {
    let mut file = File::create(EXPORT_FILENAME.as_str()).unwrap();
    write!(file, "// DO NOT EDIT. THIS FILE WAS AUTOMATICALLY GENERATED.\n\n");

    export!(MY_STRING, file);
    export!(CONCATENATED, file);
}

fn main() {
    export_all();
}

There may be a way to integrate this feature into tsync by using tsync as a library, as you have already implemented. Please share any thoughts!

@Wulf Wulf reopened this Feb 3, 2023
@Wulf
Copy link
Owner

Wulf commented Feb 4, 2023

Great solution @code-mart! Thank you for sharing. That's definitely an elegant way to go about static values.

There's one adaptation which may make it easier to integrate with tsync. It would be to have the #[tsync] macro keep track of all statics using something like inventory. That way, before the tsync binary is run, it will have a list of your values and their identifiers all ready without needing a compilation step in between. We could either force users to specify the identifier's : type (by raising an error if not specified) or guess the type using serialization.

Definitely a great feature to add! This alongside @AravindPrabhs's cargo expansion would make tsync more powerful than it was initially intended to be 😅

🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants