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

Vectorize a string slice at compile time ? #26

Open
ShellCode33 opened this issue Dec 18, 2023 · 3 comments
Open

Vectorize a string slice at compile time ? #26

ShellCode33 opened this issue Dec 18, 2023 · 3 comments

Comments

@ShellCode33
Copy link

Hey, thanks a lot for your work!

I adapted your CSV example to this:

const TEST: &str = env!("TEST");

static PARSED: [&str; 2] = iter::collect_const!(&str =>
    string::split(TEST, ","),
        map(string::trim),
);

Unfortunately the Rust compiler doesn't let me compile the code if there are not exactly 4 delimiters in the TEST environment variable. I looked at the documentation and didn't find anything that would allow me to use any size without having to change the source code.

I'm pretty new to Rust and I'm not even sure what I'm asking for is possible, but I imagined one of the two things:

  • Convert the slice to a vector using some macro magic:
static PARSED: Vec<&str> = konst::vectorize!(iter::collect_const!(&str =>
    string::split(TEST, ","),
        map(string::trim),
));
  • Be able to count occurrences of a character:
static ENTRIES_COUNT = iter::count_const!(TEST, ',');
static PARSED: [&str; ENTRIES_COUNT] = iter::collect_const!(&str =>
    string::split(TEST, ","),
        map(string::trim),
);

I'm pretty sure there are better solutions than this (if any), this is just to illustrate my need.

Let me know what you think!

@ShellCode33
Copy link
Author

ShellCode33 commented Dec 18, 2023

I came up with a build.rs script which computes the size and put it in a new environment variable:

static ENTRIES_COUNT = unwrap_ctx!(parse_usize(env!("ENTRIES_COUNT")));
static PARSED: [&str; ENTRIES_COUNT] = iter::collect_const!(&str =>
    string::split(TEST, ","),
        map(string::trim),
);

This is not ideal, but it works

@rodrimati1992
Copy link
Owner

rodrimati1992 commented Dec 18, 2023

While you can't collect into an array of unknown size, you can collect into a slice, then use try_into_array to convert it to an array.

use ::konst::{iter, slice, string, unwrap_ctx};

const TEST: &str = "foo, bar , baz,qux ";

const PARSED_SLICE: &[&str] = &iter::collect_const!(&str =>
    string::split(TEST, ","),
        map(string::trim),
);

static PARSED_ARRAY: [&str; PARSED_SLICE.len()] = *unwrap_ctx!(slice::try_into_array(PARSED_SLICE));

fn main() {
    assert_eq!(PARSED_ARRAY, ["foo", "bar", "baz", "qux"]);
}

If the slice works for you (which the suggestion to collect into a Vec seems to imply), you can skip the "converting it into an array" part.

@ShellCode33
Copy link
Author

Works like a charm, thanks a lot !

Don't you think it would still make sense to provide a helper function/macro to do this ? I feel like it's a lot of boilerplate for something as simple

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

2 participants