1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*!
# fl2rust
A fluid (fltk ui designer) file to Rust transpiler.

### As an executable
You can run fl2rust on the command-line by installing using cargo-install:
```ignore
$ cargo install fl2rust
```
Then run:
```ignore
$ fl2rust <fl-file>.fl > <output-file>.rs
```

### As a library
To automate things through cargo, you can use fl2rust as a library by adding it to your build-dependencies:
```toml
# Cargo.toml
[dependencies]
fltk = "1"

[build-dependencies]
fl2rust = "0.4"
```

```rust,no_run
// build.rs
fn main() {
    use std::path::PathBuf;
    use std::env;
    println!("cargo:rerun-if-changed=src/myuifile.fl");
    let g = fl2rust::Generator::default();
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    g.in_out("src/myuifile.fl", out_path.join("myuifile.rs").to_str().unwrap()).expect("Failed to generate rust from fl file!");
}
```

```ignore
# src/myuifile.fl -> generated via fluid
# data file for the Fltk User Interface Designer (fluid)
version 1.0400
header_name {.h}
code_name {.cxx}
class UserInterface {open
} {
  Function {make_window()} {open
  } {
    Fl_Window {} {open selected
      xywh {138 161 440 355} type Double visible
    } {
      Fl_Button but {
        label {Click me}
        xywh {175 230 95 45}
      }
    }
  }
}
```

```rust,ignore
// src/myuifile.rs
#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(clippy::needless_update)]

include!(concat!(env!("OUT_DIR"), "/myuifile.rs"));
```

```rust,ignore
// src/main.rs
use fltk::*;
mod myuifile;

fn main() {
    let app = app::App::default();
    let mut ui = myuifile::UserInterface::make_window();
    ui.but.set_callback(move |_| {
        println!("Works!");
    });
    app.run().unwrap();
}
```
*/

#![allow(clippy::needless_doctest_main)]

pub mod gen;
pub mod parser;
mod reserved;
mod utils;

use std::error;
use std::fs;
use std::path::*;

/// Generator struct
#[derive(Default)]
pub struct Generator {}

impl Generator {
    /// Takes an input and output files
    pub fn in_out<P: AsRef<Path>>(
        &self,
        inpath: P,
        outpath: P,
    ) -> Result<(), Box<dyn error::Error>> {
        fs::write(
            outpath,
            gen::generate(&parser::parse(&fs::read_to_string(inpath)?)),
        )?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        use super::*;
        let g = Generator::default();
        g.in_out("fl_tests/fl.fl", "fl_tests/fl.rs")
            .expect("Failed to generate rust from fl file!");
        g.in_out("fl_tests/fl2.fl", "fl_tests/fl2.rs")
            .expect("Failed to generate rust from fl file!");
        g.in_out("fl_tests/unt.fl", "fl_tests/unt.rs")
            .expect("Failed to generate rust from fl file!");
    }
}