artichoke/lib.rs
1#![warn(clippy::all, clippy::pedantic, clippy::undocumented_unsafe_blocks)]
2#![allow(
3 clippy::let_underscore_untyped,
4 reason = "https://github.com/rust-lang/rust-clippy/pull/10442#issuecomment-1516570154"
5)]
6#![allow(
7 clippy::question_mark,
8 reason = "https://github.com/rust-lang/rust-clippy/issues/8281"
9)]
10#![allow(clippy::manual_let_else, reason = "manual_let_else was very buggy on release")]
11#![allow(clippy::missing_errors_doc, reason = "A lot of existing code fails this lint")]
12#![allow(
13 clippy::unnecessary_lazy_evaluations,
14 reason = "https://github.com/rust-lang/rust-clippy/issues/8109"
15)]
16#![cfg_attr(
17 test,
18 allow(clippy::non_ascii_literal, reason = "tests sometimes require UTF-8 string content")
19)]
20#![allow(unknown_lints)]
21#![warn(
22 missing_copy_implementations,
23 missing_debug_implementations,
24 missing_docs,
25 rust_2024_compatibility,
26 trivial_casts,
27 trivial_numeric_casts,
28 unused_qualifications,
29 variant_size_differences
30)]
31
32//! Artichoke Ruby
33//!
34//! This crate is a Rust and Ruby implementation of the [Ruby programming
35//! language][rubylang]. Artichoke is not production-ready, but intends to be a
36//! [MRI-compliant][rubyspec] implementation of [recent MRI Ruby][mri-target].
37//!
38//! [mri-target]: https://github.com/artichoke/artichoke/blob/trunk/RUBYSPEC.md#mri-target
39//!
40//! This crate provides:
41//!
42//! - An embeddable Ruby interpreter, which can be created with the
43//! [`interpreter`] function.
44//! - A Rust and Ruby implementation of Ruby Core and Standard Library using
45//! high-quality Rust dependencies and modern Ruby.
46//! - Support for injecting Rust code and types into the interpreter with a
47//! rubygems-style [`File`](prelude::File) API.
48//! - The ability to disable parts of the interpreter VM or library functions at
49//! compile time. For example, deny access to the system environ by disabling
50//! the `core-env-system` feature.
51//!
52//! ## Usage
53//!
54//! You can create an interpreter and begin executing code on it:
55//!
56//! ```
57//! use artichoke::prelude::*;
58//!
59//! # fn example() -> Result<(), Error> {
60//! let mut interp = artichoke::interpreter()?;
61//! let result = interp.eval(b"2 + 5")?;
62//! # interp.close();
63//! # Ok(())
64//! # }
65//! # example().unwrap();
66//! ```
67//!
68//! Artichoke supports calling Ruby functions from Rust and converting between
69//! Ruby boxed values and Rust native types:
70//!
71//! ```
72//! use artichoke::prelude::*;
73//!
74//! # fn example() -> Result<(), Error> {
75//! let mut interp = artichoke::interpreter()?;
76//! let s = interp.try_convert_mut("💎")?;
77//! let codepoint = s.funcall(
78//! &mut interp,
79//! "ord",
80//! &[], /* args */
81//! None, /* block */
82//! )?;
83//! let codepoint = codepoint.try_convert_into::<u32>(&interp)?;
84//! assert_eq!(128142, codepoint);
85//! # interp.close();
86//! # Ok(())
87//! # }
88//! # example().unwrap();
89//! ```
90//!
91//! ## Crate Features
92//!
93//! All features are enabled by default.
94//!
95//! The features exposed by this crate are unstable. Please refer to the
96//! documentation in the [source `Cargo.toml`].
97//!
98//! [rubylang]: https://www.ruby-lang.org/
99//! [rubyspec]: https://github.com/ruby/spec
100//! [source `Cargo.toml`]: https://github.com/artichoke/artichoke/blob/trunk/Cargo.toml
101
102#![doc(html_root_url = "https://docs.rs/artichoke/0.1.0-pre.0")]
103#![doc(html_favicon_url = "https://www.artichokeruby.org/favicon-32x32.png")]
104#![doc(html_logo_url = "https://www.artichokeruby.org/artichoke-logo.svg")]
105
106// Ensure code blocks in `README.md` compile
107#[cfg(doctest)]
108#[doc = include_str!("../README.md")]
109mod readme {}
110
111pub use artichoke_backend as backend;
112
113#[cfg(feature = "backtrace")]
114pub mod backtrace;
115#[cfg(feature = "cli")]
116mod filename;
117pub mod parser;
118#[cfg(feature = "cli")]
119pub mod repl;
120#[cfg(feature = "cli")]
121pub mod ruby;
122
123/// A "prelude" for users of the `artichoke` crate.
124///
125/// This prelude is similar to the standard library's prelude in that you'll
126/// almost always want to import its entire contents, but unlike the standard
127/// library's prelude, you'll have to do so manually:
128///
129/// ```
130/// use artichoke::prelude::*;
131/// ```
132///
133/// The prelude may grow over time as additional items see ubiquitous use.
134pub mod prelude {
135 pub use artichoke_backend::prelude::*;
136}
137
138use artichoke_backend::release_metadata::ReleaseMetadata;
139pub use artichoke_backend::{Artichoke, Error};
140
141/// Create a new Artichoke Ruby interpreter.
142///
143/// # Errors
144///
145/// If the underlying Artichoke VM backend cannot be initialized, an error is
146/// returned.
147///
148/// If Artichoke Ruby Core or Standard Library cannot be initialized, an error
149/// is returned.
150pub fn interpreter() -> Result<Artichoke, Error> {
151 let release = ReleaseMetadata::new()
152 .with_ruby_copyright(env!("RUBY_COPYRIGHT"))
153 .with_ruby_description(env!("RUBY_DESCRIPTION"))
154 .with_ruby_engine_version(env!("CARGO_PKG_VERSION"))
155 .with_ruby_patchlevel("0")
156 .with_ruby_platform(env!("RUBY_PLATFORM"))
157 .with_ruby_release_date(env!("RUBY_RELEASE_DATE"))
158 .with_ruby_revision(env!("RUBY_REVISION"))
159 .with_ruby_version("3.1.2") // Artichoke targets MRI Ruby 3.1.2
160 .with_artichoke_compiler_version(Some(env!("ARTICHOKE_COMPILER_VERSION")));
161 artichoke_backend::interpreter_with_config(release)
162}