Как можно экспортировать структуру с константами из Rust в JavaScript, используя WebAssembly и Wasm-Pack?

Как я могу экспортировать структуру <code>Options</code> из библиотеки <a href="https://github.com/pulldown-cmark/pulldown-cmark" rel="nofollow">pulldown-cmark</a>? Я понимаю, что создать полный аналог может быть затруднительно, поэтому ищу упрощенный вариант. Например, мне нужно, чтобы в JavaScript был доступен объект такого вида: <br/> <br/> <pre><code class="javascript">const FLAGS = {
  ENABLE_TABLES: 1 &lt;&lt; 1,
  ENABLE_FOOTNOTES: 1 &lt;&lt; 2,
  ENABLE_STRIKETHROUGH: 1 &lt;&lt; 3,
}</code></pre> <br/> <br/> Или чтобы константы были определены по отдельности: <br/> <br/> <pre><code class="javascript">const ENABLE_TABLES = 1 &lt;&lt; 1;
const ENABLE_FOOTNOTES = 1 &lt;&lt; 2;
const ENABLE_STRIKETHROUGH = 1 &lt;&lt; 3;</code></pre> <br/> <br/> Я пробовал использовать следующий пример: <br/> <br/> <pre><code class="rust">#[wasm_bindgen]
pub struct Flags {
    flag1: u32,
    flag2: u32,
}

#[wasm_bindgen]
impl Flags {
    #[wasm_bindgen(constructor)]
    pub fn new() -&gt; Flags {
        Flags {
            flag1: 1,
            flag2: 2,
         }
    }
}</code></pre> <br/> <br/> Однако, после вызова <code>new Flags()</code> в JavaScript объект не содержит полей <code>flag1</code> и <code>flag2</code>. Как можно решить эту проблему?
  • 23 января 2025 г. 8:44
Ответы на вопрос 1
Для того чтобы экспортировать константы из Rust в JavaScript с использованием WebAssembly и Wasm-Pack, вам потребуется немного изменить ваш Rust-код с использованием `#[wasm_bindgen]` для создания статических методов или свойств.

Если вы хотите экспортировать константы, такие как в вашем примере с `FLAGS`, вы можете сделать это следующим образом:

1. Откройте ваш файл `lib.rs` или созданный Rust-файл.
2. Импортируйте нужные библиотеки и создайте структуру, используя `#[wasm_bindgen]`.

Вот пример, как это можно сделать:

```rust
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn enable_tables() -> u32 {
    1 << 1 // 2
}

#[wasm_bindgen]
pub fn enable_footnotes() -> u32 {
    1 << 2 // 4
}

#[wasm_bindgen]
pub fn enable_strikethrough() -> u32 {
    1 << 3 // 8
}

#[wasm_bindgen]
pub fn get_flags() -> JsValue {
    let flags = js_sys::Object::new();
    
    js_sys::Reflect::set(&flags, &"ENABLE_TABLES".into(), &enable_tables().into()).unwrap();
    js_sys::Reflect::set(&flags, &"ENABLE_FOOTNOTES".into(), &enable_footnotes().into()).unwrap();
    js_sys::Reflect::set(&flags, &"ENABLE_STRIKETHROUGH".into(), &enable_strikethrough().into()).unwrap();
    
    JsValue::from(flags)
}
```

### Использование

После компиляции Rust-кода в WebAssembly с помощью `wasm-pack`, в JavaScript вы сможете использовать экспортированные функции следующим образом:

```javascript
import { get_flags } from './your_project'; // Путь к вашему скомпилированному файлу

const FLAGS = get_flags();

// Теперь вы можете использовать FLAGS
console.log(FLAGS.ENABLE_TABLES); // 2
console.log(FLAGS.ENABLE_FOOTNOTES); // 4
console.log(FLAGS.ENABLE_STRIKETHROUGH); // 8
```

### Примечание

В этом коде мы создаем три функции для каждой константы, возвращая значения, соответствующие флагам. Также можно создать объект `flags`, в который добавляем все ваши константы, и возвращаем этот объект. 

Таким образом, при использовании WebAssembly вы можете из Rust экспортировать константы в очень удобном формате для JavaScript, который соответствует вашим требованиям.
Похожие вопросы