artichoke_core/
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#![allow(
17    clippy::module_name_repetitions,
18    reason = "incompatible with how code is organized in private modules"
19)]
20#![cfg_attr(
21    test,
22    allow(clippy::non_ascii_literal, reason = "tests sometimes require UTF-8 string content")
23)]
24#![allow(unknown_lints)]
25#![warn(
26    missing_copy_implementations,
27    missing_debug_implementations,
28    missing_docs,
29    rust_2024_compatibility,
30    trivial_casts,
31    trivial_numeric_casts,
32    unused_qualifications,
33    variant_size_differences
34)]
35#![forbid(unsafe_code)]
36// Enable feature callouts in generated documentation:
37// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
38//
39// This approach is borrowed from tokio.
40#![cfg_attr(docsrs, feature(doc_cfg))]
41#![cfg_attr(docsrs, feature(doc_alias))]
42
43//! This crate provides a set of traits that, when implemented, comprise a
44//! complete Ruby interpreter.
45//!
46//! `artichoke-core` is `no_std` + `alloc` with an optional (enabled by default)
47//! `std` feature.
48//!
49//! Interpreters implement the traits in Artichoke Core to indicate which
50//! capabilities they offer. Defining interpreters by their capabilities allows
51//! for interpreter agnostic implementations of Ruby Core and Standard Library.
52//!
53//! # Interpreter APIs
54//!
55//! Artichoke Core defines traits for the following interpreter capabilities:
56//!
57//! - [`ClassRegistry`][core-class-registry]: Define and store class specs for
58//!   Ruby `Class`es.
59//! - [`CoerceToNumeric`][core-coerce-numeric]: Coerce Ruby values to native
60//!   numerics (floats and integers).
61//! - [`Debug`][core-debug]: Provide debugging and `Exception` message support.
62//! - [`DefineConstant`][core-define-constant]: Define global, class, and module
63//!   constants to be arbitrary Ruby [`Value`][core-value]s.
64//! - [`Eval`][core-eval]: Execute Ruby source code on an interpreter from
65//!   various sources.
66//! - [`Globals`][core-globals]: Get, set, and unset interpreter-level global
67//!   variables.
68//! - [`Hash`][core-hash]: Hashing functions such as building hashers.
69//! - [`Intern`][core-intern]: Intern byte strings to a cheap to copy and compare
70//!   symbol type.
71//! - [`Io`][core-io]: External I/O APIs, such as writing to the standard output
72//!   of the current process.
73//! - [`LoadSources`][core-load-sources]: [Require][kernel#require] source code
74//!   from interpreter disk or [`File`][core-file] gems.
75//! - [`ModuleRegistry`][core-module-registry]: Define and store module spec for
76//!   Ruby `Module`s.
77//! - [`Parser`][core-parser]: Manipulate the parser state, e.g. setting the
78//!   current filename.
79//! - [`Prng`][core-prng]: An interpreter-level pseudorandom number generator
80//!   that is the backend for [`Random::DEFAULT`].
81//! - [`Regexp`][core-regexp]: Manipulate [`Regexp`][regexp-globals] global
82//!   state.
83//! - [`ReleaseMetadata`][core-releasemetadata]: Enable interpreters to describe
84//!   themselves.
85//! - [`TopSelf`][core-topself]: Access to the root execution context.
86//! - [`Warn`][core-warn]: Emit warnings.
87//!
88//! [core-class-registry]: class_registry::ClassRegistry
89//! [core-coerce-numeric]: coerce_to_numeric::CoerceToNumeric
90//! [core-convert-module]: convert
91//! [core-debug]: debug::Debug
92//! [core-define-constant]: constant::DefineConstant
93//! [core-value]: value::Value
94//! [core-eval]: eval::Eval
95//! [core-globals]: globals::Globals
96//! [core-hash]: hash::Hash
97//! [core-intern]: intern::Intern
98//! [core-io]: io::Io
99//! [core-load-sources]: load::LoadSources
100//! [core-file]: file::File
101//! [core-module-registry]: module_registry::ModuleRegistry
102//! [core-parser]: parser::Parser
103//! [core-prng]: prng::Prng
104//! [core-regexp]: regexp::Regexp
105//! [core-releasemetadata]: release_metadata::ReleaseMetadata
106//! [core-topself]: top_self::TopSelf
107//! [core-warn]: warn::Warn
108//!
109//! Artichoke Core also describes what capabilities a Ruby
110//! [`Value`](value::Value) must have and how to [convert] between Ruby VM and
111//! Rust types.
112//!
113//! # Examples
114//!
115//! [`artichoke-backend`](https://artichoke.github.io/artichoke/artichoke_backend/)
116//! is one implementation of the `artichoke-core` traits.
117//!
118//! To use all the APIs defined in Artichoke Core, bring the traits into
119//! scope by importing the prelude:
120//!
121//! ```
122//! use artichoke_core::prelude::*;
123//! ```
124//!
125//! # Crate features
126//!
127//! All features are enabled by default:
128//!
129//! - **std**: By default, `artichoke-core` is `no_std` + `alloc`. Enabling
130//!   this feature adds several trait methods that depend on `OsStr` and `Path`
131//!   as well as several implementations of `std::error::Error`.
132//!
133//! [Kernel#require]: https://ruby-doc.org/core-3.1.2/Kernel.html#method-i-require
134//! [`Random::DEFAULT`]: https://ruby-doc.org/core-3.1.2/Random.html#DEFAULT
135//! [`Regexp`]: https://ruby-doc.org/core-3.1.2/Regexp.html#class-Regexp-label-Special+global+variables
136//! [convert]: crate::convert
137
138#![no_std]
139#![doc(html_root_url = "https://artichoke.github.io/artichoke/artichoke_core")]
140#![doc(html_favicon_url = "https://www.artichokeruby.org/favicon-32x32.png")]
141#![doc(html_logo_url = "https://www.artichokeruby.org/artichoke-logo.svg")]
142
143// Ensure code blocks in `README.md` compile
144#[cfg(doctest)]
145#[doc = include_str!("../README.md")]
146mod readme {}
147
148extern crate alloc;
149#[cfg(feature = "std")]
150extern crate std;
151
152pub mod class_registry;
153pub mod coerce_to_numeric;
154pub mod constant;
155pub mod convert;
156pub mod debug;
157pub mod eval;
158pub mod file;
159pub mod globals;
160pub mod hash;
161pub mod intern;
162pub mod io;
163pub mod load;
164pub mod module_registry;
165pub mod parser;
166pub mod prng;
167pub mod regexp;
168pub mod release_metadata;
169pub mod top_self;
170pub mod types;
171pub mod value;
172pub mod warn;
173
174/// A "prelude" for users of the `artichoke-core` crate.
175///
176/// This prelude is similar to the standard library's prelude in that you'll
177/// almost always want to import its entire contents, but unlike the standard
178/// library's prelude, you'll have to do so manually:
179///
180/// ```
181/// use artichoke_core::prelude::*;
182/// ```
183///
184/// The prelude may grow over time as additional items see ubiquitous use.
185pub mod prelude {
186    pub use crate::class_registry::ClassRegistry;
187    pub use crate::coerce_to_numeric::CoerceToNumeric;
188    pub use crate::constant::DefineConstant;
189    pub use crate::convert::{Convert, ConvertMut, TryConvert, TryConvertMut};
190    pub use crate::debug::Debug;
191    pub use crate::eval::Eval;
192    pub use crate::file::File;
193    pub use crate::globals::Globals;
194    pub use crate::hash::Hash;
195    pub use crate::intern::Intern;
196    pub use crate::io::Io;
197    pub use crate::load::LoadSources;
198    pub use crate::module_registry::ModuleRegistry;
199    pub use crate::parser::{IncrementLinenoError, Parser};
200    pub use crate::prng::Prng;
201    pub use crate::regexp::Regexp;
202    pub use crate::release_metadata::ReleaseMetadata;
203    pub use crate::top_self::TopSelf;
204    pub use crate::types::{Ruby, Rust};
205    pub use crate::value::Value;
206    pub use crate::warn::Warn;
207}