diff --git a/doc/DSC/dscx.txt b/doc/DSC/dscx.txt new file mode 100644 index 0000000..fa4e70e --- /dev/null +++ b/doc/DSC/dscx.txt @@ -0,0 +1,126 @@ +include maths::sqrt + +trait AsUnit { + fn unit(self) -> Self; +} + +class Point2 { + let x: isize, + let y: isize, + + fn len(self) -> isize { + sqrt(self.x * self.x + self.y * self.y) + } +} + +// can inherit from a single class + many traits +class Point3: Point2 + AsUnit { + let z: isize,` + + fn len(self) -> isize { + // implicit return of internal expressions + sqrt(self.x * self.x + self.y * self.y + self.z * self.z) + } + + fn AsUnit.unit(self) -> Self { + let len = self.len(); + Self { + x: self.x / len, + y: self.y / len, + z: self.y / len, + } + } +} + +fn do_matches(val: AsUnit) -> bool { + + // can use kotlin-style "is" syntax to find sub-classes and implementors. + if match val { + is Point3 => true, // only Point3 as it has no subclasses. + // this also implicitly downcasts us to a Point3 so we can use methods specific to this class! + is Point2 => true, // returns true for Point2 and Point3 as it is a subclass + is AsUnit => true, // always true. + } { return true; } + + unreachable() // this should probably crash the program + + // we can match against any boolean expression. this lazily evaluates each arm one by one. + match { + do_some_processing() == 1 => println("success!") { style => style.colour = Colour::Red } + something_else() == 1 => println!("success") // we can omit the trailing lambda when it's + + // alternative syntax for the same thing as above! + val is Point3 => { return true; } + val is AsUnit => { return true; } + false == true => { return false; } + }; + + + + // of course normal rust matches also apply +} + + +/* uilib.dscx */ + +class UiBuilder { + ... + fn text_entry() -> Interaction +} + +class Interaction { + fn clicked() -> bool; +} + +/* app.dscx */ + +pub enum Action { + SubmitForm(PasswordForm) +} + +class PasswordForm { + let username: String, + let password: String, +} + + +class UserInterface { + const MESSAGE: str = "Run Emulator"; + let form: PasswordForm; + let state: EmulatorState; + + fn new(state: EmulatorState) -> Self { + Self { + form: PasswordForm { + username: String::new(), + password: String::new() + }, + state + } + } + + fn ui(self, ui: UiBuilder) -> Action { + + ui_lib::Form(self.form, ui, "login") { form, ui -> + ui.text_entry(form.username) { view -> + view.placeholder = "enter username"; + } + + ui.text_entry(form.password); // also acceptable syntax. placeholder has a default value! + + if ui.button("Submit").clicked() { + return Action::SubmitForm(form); + } + } + + ui.vertical { + my_lib::StatusIndicator(self.state.status, ui); + + if ui.button("Run Emulator").clicked() { + self.state.run(); + } + } + + } +} +