bedquilt_io/
lib.rs

1//! This crate provides a safe, idiomatic, mid-level abstraction over
2//! [Glk](https://www.eblong.com/zarf/glk/Glk-Spec-075.html) and other system
3//! facilities that are available from within the [Glulx virtual
4//! machine](https://www.eblong.com/zarf/glulx/Glulx-Spec.html). You can write
5//! Rust code which targets Glulx by depending on this crate, compiling for
6//! `wasm32-unknown-unknown`, and then using
7//! [Wasm2Glulx](https://bedquilt.io/manual/wasm2glulx/cli.html) to generate a
8//! Glulx story file.
9//! 
10//! You can think of `bedquilt-io` (alongside [`core`], [`alloc`], and
11//! [`hashbrown`]) as your substitute for `std` when developing for Glulx. Rust
12//! does already have a `std` crate for `wasm32-unknown-unknown`, but it is
13//! mostly useless: almost everything in it just panics or returns an
14//! `Unimplemented` error. If you want to use it anyway, you will need to
15//! disable this crate's `panic_handler` and `global_allocator` features to
16//! prevent conflict with the ones that `std` provides. It is recommended,
17//! however, to make your program `no_std`, as `bedquilt-io` should already
18//! provide everything you need.
19//! 
20//! In the future, `bedquilt-io` will also support native compilation, using a
21//! pure-Rust implementation of the
22//! [RemGlk](https://www.eblong.com/zarf/glk/remglk/docs.html) protocol.
23//! However, this is not yet implemented, and this crate will fail to compile on
24//! for target other than `wasm32-unknown-unknown`. References in this
25//! documentation to behavior on "other platforms" should be understood in the
26//! future tense.
27//! 
28//! `bedquilt-io` is implemented around an included async executor. Your
29//! program's `glulx_main` function should use [`task::spawn`] to start one or
30//! more asynchronous tasks, and then call [`task::run`] to run them all to
31//! completion. One of your tasks can then create a root window (typically a
32//! [`TextBufferWindow`](win::TextBufferWindow)) using
33//! [`win::Window::create_as_root`] and use the traits it implements to perform
34//! IO asynchronously. A trivial program which reads keyboard input in a loop
35//! and echoes it back looks like this:
36//! 
37//! ```ignore
38//! #![no_std]
39//! #![no_main]
40//! 
41//! use bedquilt_io::win::{LineInput, TextBufferWindow, Window};
42//! use core::fmt::Write;
43//!
44//! #[no_mangle]
45//! extern "C" fn glulx_main() {
46//!     bedquilt_io::task::spawn(main());
47//!     bedquilt_io::task::run();   
48//! }
49//!
50//! async fn main() {
51//!     let mut root = TextBufferWindow::create_as_root().unwrap();
52//!     loop {
53//!         let input = root.request_line("").unwrap().await;
54//!         writeln!(root, "{}", input.input).unwrap();
55//!     }
56//! }
57//! ```
58//! 
59//! Glk requires programs to query for a "gestalt" before attempting to use
60//! certain optional features. In Bedquilt, this is not necessary. If you want
61//! to do something possibly-unsupported, just try it, and if the necessary
62//! gestalt is missing you'll get back
63//! [`Error::Unsupported`](error::Error::Unsupported).
64
65#![warn(missing_debug_implementations, missing_docs)]
66#![cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), no_std)]
67extern crate alloc;
68
69pub mod error;
70pub mod fs;
71pub mod random;
72mod reactor;
73pub mod sync;
74mod sys;
75pub mod sound;
76pub mod task;
77pub mod time;
78pub mod win;
79
80pub use sys::exit;