1 //! # Ion - the pipe-oriented embedded language
2 //!
3 //! Ion is an embeddable shell for rust. This means your users can benefit from a fully-fledged
4 //! programming language to configure your application, rather than predefined layouts imposed by
5 //! formats like yaml. This also means the configuration can be completely responsive and react to
6 //! events in any way the user sees fit.
7 //!
8 //! ## Getting started
9 //!
10 //! ```toml
11 //! [dependencies]
12 //! ion_shell = "1.0"
13 //! ```
14 //!
15 //! ## Documentation
16 //!  - [Ion programming language manual](https://doc.redox-os.org/ion-manual/)
17 //!
18 //! ## Demo
19 //!
20 //! ```rust
21 //! use ion_shell::{builtins::Status, types, BuiltinFunction, BuiltinMap, Shell, Value};
22 //! use std::{cell::RefCell, fs::File, rc::Rc, thread, time};
23 //!
24 //! enum Layout {
25 //!     Simple,
26 //!     Complex(String),
27 //! }
28 //!
29 //! fn main() {
30 //!     let mut i = 0;
31 //!     let layout = RefCell::new(Layout::Simple); // A state for your application
32 //!
33 //!     // Create a custom callback to update your state when called by a script
34 //!     let set_layout: BuiltinFunction = &move |args: &[types::Str], shell: &mut Shell| {
35 //!         *layout.borrow_mut() = if let Some(text) = args.get(0) {
36 //!             Layout::Complex(text.to_string())
37 //!         } else {
38 //!             Layout::Simple
39 //!         };
40 //!         Status::SUCCESS
41 //!     };
42 //!
43 //!     // Create a shell
44 //!     let mut shell = Shell::new();
45 //!
46 //!     // Register the builtins
47 //!     shell.builtins_mut().add("layout", set_layout, "Set the application layout");
48 //!
49 //!     // Read a file and execute it
50 //!     if let Ok(file) = File::open("/home/user/.config/my-application/config.ion") {
51 //!         if let Err(why) = shell.execute_command(file) {
52 //!             println!("ERROR: my-application: error in config file: {}", why);
53 //!         }
54 //!     }
55 //!
56 //!     for _ in 0..255 {
57 //!         i += 1;
58 //!         // call a user-defined callback function named on_update
59 //!         if let Some(Value::Function(function)) = shell.variables().get("on_update") {
60 //!             if let Err(why) =
61 //!                 shell.execute_function(&function.clone(), &["ion", &i.to_string()])
62 //!             {
63 //!                 println!("ERROR: my-application: error in on_update callback: {}", why);
64 //!             }
65 //!         }
66 //!
67 //!         thread::sleep(time::Duration::from_millis(5));
68 //!     }
69 //! }
70 //! ```
71 
72 #![allow(unknown_lints)]
73 #![deny(missing_docs)]
74 #![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
75 #![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
76 use ion_ranges as ranges;
77 
78 /// The various types used for storing values
79 #[macro_use]
80 pub mod types;
81 /// Direct access to the parsers
82 #[macro_use]
83 pub mod parser;
84 mod assignments;
85 /// Access to the predefined builtins
86 pub mod builtins;
87 /// Expand the AST to create pipelines
88 pub mod expansion;
89 mod memory;
90 mod shell;
91 
92 pub use nix::sys::signal::Signal;
93 
94 pub(crate) use self::memory::IonPool;
95 pub use crate::{
96     builtins::{BuiltinFunction, BuiltinMap},
97     shell::*,
98 };
99 pub use builtins_proc::builtin;
100