//! Extention trait pattern helper.
//!
//! _The author of this crate is not good at English._  
//! _Forgive me if the document is hard to read._
//!
//! # What is this?
//!
//! This simple crate allows the [Extension Trait pattern][ExtTrait]
//! to be applied without method name collisions.
//!
//! The core idea is simply to guarantee that [`S<T>`] has no methods,
//! neither now nor in the future (there are a more other things, but
//! they're just [added bonuses](#bonus-items)).
//!
//! Of course, you can create the same one in an instant.
//! But documenting the reason why you introduced such an empty type
//! is probably not a fun task. That's where this crate comes in.
//!
//! # Extention Trait pattern
//!
//! A pattern for enabling more places to be written using method call notation.
//!
//! Method call notation has the following characteristics compared to
//! standard function call notation.
//!
//! - The main argument is clear
//! - Method chaining is supported
//! - IDE autocomplete is efficient
//!
//! Therefore, even if the functionality of the function version and
//! the method version are the same, the latter is generally preferred.
//!
//! However, we cannot add methods to other crate types. Thus, in the
//! Extension Trait pattern, methods are added not to the type itself,
//! but to the trait that the type implements.
//!
//! In the following example, the `map_nan` method is added
//! to `f32` in the `std` crate.
//!
//! ```rust
//! fn main() {
//!     let x = f32::NAN;
//!     assert_eq!(x.map_nan(0.0), 0.0);
//! }
//!
//! pub trait F32Ext {
//!     fn map_nan(self, substitute: f32) -> f32;
//! }
//!
//! impl F32Ext for f32 {
//!     fn map_nan(self, substitute: f32) -> f32 {
//!         if self.is_nan() { substitute } else { self }
//!     }
//! }
//! ```
//!
//! # Target problem and solution
//!
//! In the previous example, a name collision occurs if a new version of Rust
//! introduced `map_nan` to `f32`. In this case, an error will occur if counts
//! and types of arguments differ; otherwise, the target will be changed silently
//! (in spec as of 2026). And this problem is treated as "possibly breaking" in
//! [official document][ChangeCategories] (I feel uneasy about this). And if it
//! becomes a problem, it instructs to use fully qualified syntax. However, it
//! does not offer the benefits like method notation.
//!
//! This issue can be solved by this crate as follows.
//!
//! ```rust
//! use subject::prelude::*;
//!
//! fn main() {
//!     let x = f32::NAN;
//!     assert_eq!(S(x).map_nan(0.0), 0.0);
//! }
//!
//! pub trait F32Ext {
//!     fn map_nan(self, substitute: f32) -> f32;
//! }
//!
//! impl F32Ext for S<f32> {
//!     fn map_nan(self, substitute: f32) -> f32 {
//!         if self.0.is_nan() { substitute } else { self.0 }
//!     }
//! }
//! ```
//!
//! # Full method chain style
//!
//! `S(x)` might look a bit clunky when `x` is a method chain. You can write
//! this as `x.r#use()` by using `UseExt::r#use`. This allows you to combine
//! the entire expression into a single method chain.
//!
//! By the way, there is a potential for name collisions here, as mentioned
//! earlier, but this is unlikely to be a major issue. First, the use of
//! `UseExt` is optional. Also, as you may have noticed, using keywords as
//! identifiers helps prevent collisions.
//!
//! ```rust
//! use subject::prelude::*;
//! use subject::UseExt;
//! use std::ops::{Add, Sub};
//!
//! fn main() {
//!     let x = f32::NAN;
//!     assert_eq!(x.add(1.0).sub(1.0).r#use().map_nan(0.0), 0.0);
//! }
//!
//! pub trait F32Ext {
//!     fn map_nan(self, substitute: f32) -> f32;
//! }
//!
//! impl F32Ext for S<f32> {
//!     fn map_nan(self, substitute: f32) -> f32 {
//!         if self.0.is_nan() { substitute } else { self.0 }
//!     }
//! }
//! ```
//!
//! # Bonus items
//!
//! This crate includes several commonly used extensions. For example,
//! [`UpgetExt::upget`] performs both updates and get operations at once.
//! (For details, see the [`exts`] module document.)
//!
//! <!-- links -->
//!
//! [ExtTrait]: #extention-trait-pattern
//! [ChangeCategories]: https://doc.rust-lang.org/cargo/reference/semver.html#change-categories
//! [`UpgetExt::upget`]: exts::UpgetExt::upget

#![no_std]
#![warn(missing_docs)]

pub mod exts;
pub mod prelude;
pub use s::*;
pub use use_ext::*;

mod s;
mod use_ext;
