# Specta Elm
[](https://crates.io/crates/specta-elm)
[](https://docs.rs/specta-elm)
[](https://opensource.org/licenses/MIT)
A Rust crate for exporting Rust types to Elm, built on top of [Specta](https://github.com/specta-rs/specta). Check the official repo for more languages and frameworks to choose from.
If you can't choose another language for your graphical interface, please reach, I wanna know 😍
## Exporters
- 🚀 **SingleFile** - With a standarized Msg file [*1](#ref1).
- 📁 **MultipleFiles** - todo!()
## Unsupported in v0.1.0
- 🧬 **Generics**
- 🔗 **Recursive Types**
- 🔄 **Opaque references**
## Quick Start
Add `specta-elm` to your `Cargo.toml`:
```toml
[dependencies]
specta = { version = "2.0", features = ["derive"] }
specta-elm = "0.1"
```
Define your Rust types:
```rust
use specta::{Type};
#[derive(Type)]
struct User {
id: u32,
name: String,
email: Option<String>,
role: UserRole,
}
#[derive(Type)]
enum UserRole {
Guest,
User { permissions: Vec<String> },
Admin { level: u8, department: String },
}
#[derive(Type)]
enum ApiResult {
Success { data: String, status: u16 },
Error { message: String, code: u32 },
Loading { progress: f32 },
}
```
Example rust code:
```rust
fn main() {
let types = Types::default()
.register::<User>()
.register::<UserRole>()
.register::<ApiResult>();
Elm::init("./frontend/src")
.register::<User>()
.register::<UserRole>()
.register::<ApiResult>()
.export(SingleFile("Msg"))
.unwrap();
}
```
This generates:
```elm
```
## Type Mapping
| Elm Type | Rust Type |
| --------------- | ------------------------------------- |
| Int | `i8`, `u8`, `i16`, `u16`, `i32`, `u32`,`i64`, `u64` |
| Float | `f32`, `f64` |
| Bool | `bool` |
| String | `char` |
| | `String` |
| Maybe (Core) | `Option<T>` |
| Tuple | `(T, U)` |
| List | `Vec<T>`, `HashSet<T>` |
| Map (Core) | `HashMap<K, V>` |
## Notes
<a id="ref1"></a>
##### 1. Elm Architecture
> In the Elm architecture we use three main elements: Model View Update
> - The model represents the app, or parts of the app.
> - Through the update function, we create a new model.
> - The view function shapes that model to be rendered Html.
>
> So our main data object or object type(s) is/are the model(s).
> Another way that you see data moving around is usually a type named Msg.
> We use Msg variants as a way to carry data from one scope of the app to another.
> Msg can be carrying models, or functions to update them.
>
>> For our single file file exporter, we put all types in a Msg.elm file,
>> which we can import and use in the simplest way:
>>
>> ```elm
>> import Msg exposing (..)
>>
>> type alias Alias = Msg.SomeType
>>
>> type alias RedundantAlias = SomeType
>> ```
>
>> This clashes with the architectural/naming convention in Elm, which is
>> better represented by the multiple file exporter:
>>
>> ```elm
>> import SomeType exposing (Model)
>>
>> type alias MyType = SomeType.Model
>>
>> type alias SameType = Model
>> ```
>
>> But made my life way easier in v0.1.0 and I personally don't mind breaking
>> Elm's architectural model for this in my specific usecase. I even find useful
>> the different conventions for manually and automatically generated types.
<a id="ref2"></a>
##### 2. Another note
> In the Elm architecture we use a Model View Update
> Yeah?
## Future Features
* [ ] Multiple file exporter
> to be consistent with the Elm architecture
* [ ] Make elm.json the source of truth of everything.
> elm.json can have random keywords
> we could define a specta-elm object
> and lean heavily on project auto-detect
## Contributing
Contributions are welcome! There's no guidelines still, but feel free to reach :)
## License
This project's License is inherited from its parent project - see the [LICENSE](LICENSE).