pub struct Backend {
forks: MultiFork,
mem_db: FoundryEvmInMemoryDB,
fork_init_journaled_state: JournaledState,
active_fork_ids: Option<(LocalForkId, usize)>,
inner: BackendInner,
}
Expand description
Provides the underlying revm::Database
implementation.
A Backend
can be initialised in two forms:
§1. Empty in-memory Database
This is the default variant: an empty revm::Database
§2. Forked Database
A revm::Database
that forks off a remote client
In addition to that we support forking manually on the fly.
Additional forks can be created. Each unique fork is identified by its unique ForkId
. We treat
forks as unique if they have the same (endpoint, block number)
pair.
When it comes to testing, it’s intended that each contract will use its own Backend
(Backend::clone
). This way each contract uses its own encapsulated evm state. For in-memory
testing, the database is just an owned revm::InMemoryDB
.
Each Fork
, identified by a unique id, uses completely separate storage, write operations are
performed only in the fork’s own database, ForkDB
.
A ForkDB
consists of 2 halves:
- everything fetched from the remote is readonly
- all local changes (instructed by the contract) are written to the backend’s
db
and don’t alter the state of the remote client.
§Fork swapping
Multiple “forks” can be created Backend::create_fork()
, however only 1 can be used by the
db
. However, their state can be hot-swapped by swapping the read half of db
from one fork to
another.
When swapping forks (Backend::select_fork()
) we also update the current Env
of the EVM
accordingly, so that all block.*
config values match
When another for is selected DatabaseExt::select_fork()
the entire storage, including
JournaledState
is swapped, but the storage of the caller’s and the test contract account is
always cloned. This way a fork has entirely separate storage but data can still be shared
across fork boundaries via stack and contract variables.
§Snapshotting
A snapshot of the current overall state can be taken at any point in time. A snapshot is identified by a unique id that’s returned when a snapshot is created. A snapshot can only be reverted once. After a successful revert, the same snapshot id cannot be used again. Reverting a snapshot replaces the current active state with the snapshot state, the snapshot is deleted afterwards, as well as any snapshots taken after the reverted snapshot, (e.g.: reverting to id 0x1 will delete snapshots with ids 0x1, 0x2, etc.)
Note: State snapshots work across fork-swaps, e.g. if fork A
is currently active, then a
snapshot is created before fork B
is selected, then fork A
will be the active fork again
after reverting the snapshot.
Fields§
§forks: MultiFork
The access point for managing forks
mem_db: FoundryEvmInMemoryDB
§fork_init_journaled_state: JournaledState
The journaled_state to use to initialize new forks with
The way [revm::JournaledState
] works is, that it holds the “hot” accounts loaded from the
underlying Database
that feeds the Account and State data to the journaled_state so it
can apply changes to the state while the EVM executes.
In a way the JournaledState
is something like a cache that
- check if account is already loaded (hot)
- if not load from the
Database
(this will then retrieve the account via RPC in forking mode)
To properly initialize we store the JournaledState
before the first fork is selected
(DatabaseExt::select_fork
).
This will be an empty JournaledState
, which will be populated with persistent accounts,
See Self::update_fork_db()
.
active_fork_ids: Option<(LocalForkId, usize)>
The currently active fork database
If this is set, then the Backend is currently in forking mode
inner: BackendInner
holds additional Backend data
Implementations§
Source§impl Backend
impl Backend
Sourcepub fn spawn(fork: Option<CreateFork>) -> Self
pub fn spawn(fork: Option<CreateFork>) -> Self
Creates a new Backend with a spawned multi fork thread.
If fork
is Some
this will use a fork
database, otherwise with an in-memory
database.
Sourcepub fn new(forks: MultiFork, fork: Option<CreateFork>) -> Self
pub fn new(forks: MultiFork, fork: Option<CreateFork>) -> Self
Creates a new instance of Backend
If fork
is Some
this will use a fork
database, otherwise with an in-memory
database.
Prefer using spawn
instead.
Sourcepub(crate) fn new_with_fork(
id: &ForkId,
fork: Fork,
journaled_state: JournaledState,
) -> Self
pub(crate) fn new_with_fork( id: &ForkId, fork: Fork, journaled_state: JournaledState, ) -> Self
Creates a new instance of Backend
with fork added to the fork database and sets the fork
as active
Sourcepub fn clone_empty(&self) -> Self
pub fn clone_empty(&self) -> Self
Creates a new instance with a BackendDatabase::InMemory
cache layer for the CacheDB
pub fn insert_account_info(&mut self, address: Address, account: AccountInfo)
Sourcepub fn insert_account_storage(
&mut self,
address: Address,
slot: U256,
value: U256,
) -> Result<(), DatabaseError>
pub fn insert_account_storage( &mut self, address: Address, slot: U256, value: U256, ) -> Result<(), DatabaseError>
Inserts a value on an account’s storage without overriding account info
Sourcepub fn replace_account_storage(
&mut self,
address: Address,
storage: Map<U256, U256>,
) -> Result<(), DatabaseError>
pub fn replace_account_storage( &mut self, address: Address, storage: Map<U256, U256>, ) -> Result<(), DatabaseError>
Completely replace an account’s storage without overriding account info.
When forking, this causes the backend to assume a 0
value for all
unset storage slots instead of trying to fetch it.
Sourcepub fn state_snapshots(
&self,
) -> &StateSnapshots<BackendStateSnapshot<BackendDatabaseSnapshot>>
pub fn state_snapshots( &self, ) -> &StateSnapshots<BackendStateSnapshot<BackendDatabaseSnapshot>>
Returns all snapshots created in this backend
Sourcepub fn set_test_contract(&mut self, acc: Address) -> &mut Self
pub fn set_test_contract(&mut self, acc: Address) -> &mut Self
Sets the address of the DSTest
contract that is being executed
This will also mark the caller as persistent and remove the persistent status from the previous test contract address
This will also grant cheatcode access to the test account
Sourcepub fn set_caller(&mut self, acc: Address) -> &mut Self
pub fn set_caller(&mut self, acc: Address) -> &mut Self
Sets the caller address
Sourcepub fn set_spec_id(&mut self, spec_id: SpecId) -> &mut Self
pub fn set_spec_id(&mut self, spec_id: SpecId) -> &mut Self
Sets the current spec id
Sourcepub fn caller_address(&self) -> Option<Address>
pub fn caller_address(&self) -> Option<Address>
Returns the set caller address
Sourcepub fn has_state_snapshot_failure(&self) -> bool
pub fn has_state_snapshot_failure(&self) -> bool
Failures occurred in state snapshots are tracked when the state snapshot is reverted.
If an error occurs in a restored state snapshot, the test is considered failed.
This returns whether there was a reverted state snapshot that recorded an error.
Sourcepub fn set_state_snapshot_failure(&mut self, has_state_snapshot_failure: bool)
pub fn set_state_snapshot_failure(&mut self, has_state_snapshot_failure: bool)
Sets the state snapshot failure flag.
Sourcepub(crate) fn update_fork_db(
&self,
active_journaled_state: &mut JournaledState,
target_fork: &mut Fork,
)
pub(crate) fn update_fork_db( &self, active_journaled_state: &mut JournaledState, target_fork: &mut Fork, )
When creating or switching forks, we update the AccountInfo of the contract
Sourcepub(crate) fn update_fork_db_contracts(
&self,
accounts: impl IntoIterator<Item = Address>,
active_journaled_state: &mut JournaledState,
target_fork: &mut Fork,
)
pub(crate) fn update_fork_db_contracts( &self, accounts: impl IntoIterator<Item = Address>, active_journaled_state: &mut JournaledState, target_fork: &mut Fork, )
Merges the state of all accounts
from the currently active db into the given fork
Sourcepub fn mem_db(&self) -> &FoundryEvmInMemoryDB
pub fn mem_db(&self) -> &FoundryEvmInMemoryDB
Returns the memory db used if not in forking mode
Sourcepub fn is_active_fork(&self, id: LocalForkId) -> bool
pub fn is_active_fork(&self, id: LocalForkId) -> bool
Returns true if the id
is currently active
Sourcepub fn is_in_forking_mode(&self) -> bool
pub fn is_in_forking_mode(&self) -> bool
Returns true
if the Backend
is currently in forking mode
Sourcepub fn active_fork(&self) -> Option<&Fork>
pub fn active_fork(&self) -> Option<&Fork>
Returns the currently active Fork
, if any
Sourcepub fn active_fork_mut(&mut self) -> Option<&mut Fork>
pub fn active_fork_mut(&mut self) -> Option<&mut Fork>
Returns the currently active Fork
, if any
Sourcepub fn active_fork_db(&self) -> Option<&CacheDB<SharedBackend>>
pub fn active_fork_db(&self) -> Option<&CacheDB<SharedBackend>>
Returns the currently active ForkDB
, if any
Sourcepub fn active_fork_db_mut(&mut self) -> Option<&mut CacheDB<SharedBackend>>
pub fn active_fork_db_mut(&mut self) -> Option<&mut CacheDB<SharedBackend>>
Returns the currently active ForkDB
, if any
Sourcepub fn db(&self) -> &dyn Database<Error = DatabaseError>
pub fn db(&self) -> &dyn Database<Error = DatabaseError>
Returns the current database implementation as a &dyn
value.
Sourcepub fn db_mut(&mut self) -> &mut dyn Database<Error = DatabaseError>
pub fn db_mut(&mut self) -> &mut dyn Database<Error = DatabaseError>
Returns the current database implementation as a &mut dyn
value.
Sourcepub(crate) fn create_db_snapshot(&self) -> BackendDatabaseSnapshot
pub(crate) fn create_db_snapshot(&self) -> BackendDatabaseSnapshot
Creates a snapshot of the currently active database
Sourcepub fn merged_logs(&self, logs: Vec<Log>) -> Vec<Log>
pub fn merged_logs(&self, logs: Vec<Log>) -> Vec<Log>
Since each Fork
tracks logs separately, we need to merge them to get all of them
Sourcepub(crate) fn initialize(&mut self, env: &EnvWithHandlerCfg)
pub(crate) fn initialize(&mut self, env: &EnvWithHandlerCfg)
Initializes settings we need to keep track of.
We need to track these mainly to prevent issues when switching between different evms
Sourcefn env_with_handler_cfg(&self, env: Env) -> EnvWithHandlerCfg
fn env_with_handler_cfg(&self, env: Env) -> EnvWithHandlerCfg
Returns the EnvWithHandlerCfg
with the current spec_id
set.
Sourcepub fn inspect<I: InspectorExt>(
&mut self,
env: &mut EnvWithHandlerCfg,
inspector: &mut I,
) -> Result<ResultAndState>
pub fn inspect<I: InspectorExt>( &mut self, env: &mut EnvWithHandlerCfg, inspector: &mut I, ) -> Result<ResultAndState>
Executes the configured test call of the env
without committing state changes.
Note: in case there are any cheatcodes executed that modify the environment, this will
update the given env
with the new values.
Sourcepub fn is_existing_precompile(&self, addr: &Address) -> bool
pub fn is_existing_precompile(&self, addr: &Address) -> bool
Returns true if the address is a precompile
Sourcefn set_init_journaled_state(&mut self, journaled_state: JournaledState)
fn set_init_journaled_state(&mut self, journaled_state: JournaledState)
Sets the initial journaled state to use when initializing forks
Sourcefn prepare_init_journal_state(&mut self) -> Result<(), BackendError>
fn prepare_init_journal_state(&mut self) -> Result<(), BackendError>
Cleans up already loaded accounts that would be initialized without the correct data from the fork.
It can happen that an account is loaded before the first fork is selected, like
getNonce(addr)
, which will load an empty account by default.
This account data then would not match the account data of a fork if it exists. So when the first fork is initialized we replace these accounts with the actual account as it exists on the fork.
Sourcefn get_block_number_and_block_for_transaction(
&self,
id: LocalForkId,
transaction: B256,
) -> Result<(u64, Block<WithOtherFields<Transaction>>)>
fn get_block_number_and_block_for_transaction( &self, id: LocalForkId, transaction: B256, ) -> Result<(u64, Block<WithOtherFields<Transaction>>)>
Returns the block numbers required for replaying a transaction
Sourcepub fn replay_until(
&mut self,
id: LocalForkId,
env: Env,
tx_hash: B256,
journaled_state: &mut JournaledState,
) -> Result<Option<Transaction>>
pub fn replay_until( &mut self, id: LocalForkId, env: Env, tx_hash: B256, journaled_state: &mut JournaledState, ) -> Result<Option<Transaction>>
Replays all the transactions at the forks current block that were mined before the tx
Returns the unmined transaction that corresponds to the given tx_hash
Trait Implementations§
Source§impl Database for Backend
impl Database for Backend
Source§type Error = DatabaseError
type Error = DatabaseError
Source§fn basic(
&mut self,
address: Address,
) -> Result<Option<AccountInfo>, Self::Error>
fn basic( &mut self, address: Address, ) -> Result<Option<AccountInfo>, Self::Error>
Source§fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>
fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error>
Source§fn storage(
&mut self,
address: Address,
index: U256,
) -> Result<U256, Self::Error>
fn storage( &mut self, address: Address, index: U256, ) -> Result<U256, Self::Error>
Source§fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error>
fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error>
Source§impl DatabaseExt for Backend
impl DatabaseExt for Backend
Source§fn select_fork(
&mut self,
id: LocalForkId,
env: &mut Env,
active_journaled_state: &mut JournaledState,
) -> Result<()>
fn select_fork( &mut self, id: LocalForkId, env: &mut Env, active_journaled_state: &mut JournaledState, ) -> Result<()>
Select an existing fork by id. When switching forks we copy the shared state
Source§fn roll_fork(
&mut self,
id: Option<LocalForkId>,
block_number: u64,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<()>
fn roll_fork( &mut self, id: Option<LocalForkId>, block_number: u64, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<()>
This is effectively the same as Self::create_select_fork()
but updating an existing
ForkId that is mapped to the LocalForkId
Source§fn load_allocs(
&mut self,
allocs: &BTreeMap<Address, GenesisAccount>,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>
fn load_allocs( &mut self, allocs: &BTreeMap<Address, GenesisAccount>, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>
Source§fn clone_account(
&mut self,
source: &GenesisAccount,
target: &Address,
journaled_state: &mut JournaledState,
) -> Result<(), BackendError>
fn clone_account( &mut self, source: &GenesisAccount, target: &Address, journaled_state: &mut JournaledState, ) -> Result<(), BackendError>
Source§fn snapshot_state(
&mut self,
journaled_state: &JournaledState,
env: &Env,
) -> U256
fn snapshot_state( &mut self, journaled_state: &JournaledState, env: &Env, ) -> U256
Source§fn revert_state(
&mut self,
id: U256,
current_state: &JournaledState,
current: &mut Env,
action: RevertStateSnapshotAction,
) -> Option<JournaledState>
fn revert_state( &mut self, id: U256, current_state: &JournaledState, current: &mut Env, action: RevertStateSnapshotAction, ) -> Option<JournaledState>
Source§fn delete_state_snapshot(&mut self, id: U256) -> bool
fn delete_state_snapshot(&mut self, id: U256) -> bool
id
Read moreSource§fn delete_state_snapshots(&mut self)
fn delete_state_snapshots(&mut self)
Source§fn create_fork(&mut self, create_fork: CreateFork) -> Result<LocalForkId>
fn create_fork(&mut self, create_fork: CreateFork) -> Result<LocalForkId>
Source§fn create_fork_at_transaction(
&mut self,
fork: CreateFork,
transaction: B256,
) -> Result<LocalForkId>
fn create_fork_at_transaction( &mut self, fork: CreateFork, transaction: B256, ) -> Result<LocalForkId>
Source§fn roll_fork_to_transaction(
&mut self,
id: Option<LocalForkId>,
transaction: B256,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<()>
fn roll_fork_to_transaction( &mut self, id: Option<LocalForkId>, transaction: B256, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<()>
Source§fn transact(
&mut self,
maybe_id: Option<LocalForkId>,
transaction: B256,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<()>
fn transact( &mut self, maybe_id: Option<LocalForkId>, transaction: B256, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<()>
Source§fn transact_from_tx(
&mut self,
tx: &TransactionRequest,
env: Env,
journaled_state: &mut JournaledState,
inspector: &mut dyn InspectorExt,
) -> Result<()>
fn transact_from_tx( &mut self, tx: &TransactionRequest, env: Env, journaled_state: &mut JournaledState, inspector: &mut dyn InspectorExt, ) -> Result<()>
Source§fn active_fork_id(&self) -> Option<LocalForkId>
fn active_fork_id(&self) -> Option<LocalForkId>
ForkId
that’s currently used in the database, if fork mode is onSource§fn active_fork_url(&self) -> Option<String>
fn active_fork_url(&self) -> Option<String>
Source§fn ensure_fork(&self, id: Option<LocalForkId>) -> Result<LocalForkId>
fn ensure_fork(&self, id: Option<LocalForkId>) -> Result<LocalForkId>
Source§fn ensure_fork_id(&self, id: LocalForkId) -> Result<&ForkId>
fn ensure_fork_id(&self, id: LocalForkId) -> Result<&ForkId>
ForkId
exists for the given local id
Source§fn diagnose_revert(
&self,
callee: Address,
journaled_state: &JournaledState,
) -> Option<RevertDiagnostic>
fn diagnose_revert( &self, callee: Address, journaled_state: &JournaledState, ) -> Option<RevertDiagnostic>
Source§fn add_persistent_account(&mut self, account: Address) -> bool
fn add_persistent_account(&mut self, account: Address) -> bool
Source§fn remove_persistent_account(&mut self, account: &Address) -> bool
fn remove_persistent_account(&mut self, account: &Address) -> bool
Source§fn is_persistent(&self, acc: &Address) -> bool
fn is_persistent(&self, acc: &Address) -> bool
Source§fn allow_cheatcode_access(&mut self, account: Address) -> bool
fn allow_cheatcode_access(&mut self, account: Address) -> bool
account
Read moreSource§fn revoke_cheatcode_access(&mut self, account: &Address) -> bool
fn revoke_cheatcode_access(&mut self, account: &Address) -> bool
Source§fn has_cheatcode_access(&self, account: &Address) -> bool
fn has_cheatcode_access(&self, account: &Address) -> bool
true
if the given account is allowed to execute cheatcodesSource§fn set_blockhash(&mut self, block_number: U256, block_hash: B256)
fn set_blockhash(&mut self, block_number: U256, block_hash: B256)
Source§fn create_select_fork(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
) -> Result<LocalForkId>
fn create_select_fork( &mut self, fork: CreateFork, env: &mut Env, journaled_state: &mut JournaledState, ) -> Result<LocalForkId>
Source§fn create_select_fork_at_transaction(
&mut self,
fork: CreateFork,
env: &mut Env,
journaled_state: &mut JournaledState,
transaction: B256,
) -> Result<LocalForkId>
fn create_select_fork_at_transaction( &mut self, fork: CreateFork, env: &mut Env, journaled_state: &mut JournaledState, transaction: B256, ) -> Result<LocalForkId>
Source§fn is_forked_mode(&self) -> bool
fn is_forked_mode(&self) -> bool
Source§fn remove_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
fn remove_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
Source§fn extend_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
fn extend_persistent_accounts(
&mut self,
accounts: impl IntoIterator<Item = Address>,
)where
Self: Sized,
Source§fn ensure_cheatcode_access(&self, account: &Address) -> Result<(), BackendError>
fn ensure_cheatcode_access(&self, account: &Address) -> Result<(), BackendError>
account
is allowed to execute cheatcodes Read moreSource§fn ensure_cheatcode_access_forking_mode(
&self,
account: &Address,
) -> Result<(), BackendError>
fn ensure_cheatcode_access_forking_mode( &self, account: &Address, ) -> Result<(), BackendError>
Self::ensure_cheatcode_access()
but only enforces it if the backend is currently
in forking modeSource§impl DatabaseRef for Backend
impl DatabaseRef for Backend
Source§type Error = DatabaseError
type Error = DatabaseError
Source§fn basic_ref(
&self,
address: Address,
) -> Result<Option<AccountInfo>, Self::Error>
fn basic_ref( &self, address: Address, ) -> Result<Option<AccountInfo>, Self::Error>
Source§fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error>
fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error>
Source§fn storage_ref(
&self,
address: Address,
index: U256,
) -> Result<U256, Self::Error>
fn storage_ref( &self, address: Address, index: U256, ) -> Result<U256, Self::Error>
Source§fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error>
fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error>
Auto Trait Implementations§
impl Freeze for Backend
impl !RefUnwindSafe for Backend
impl Send for Backend
impl Sync for Backend
impl Unpin for Backend
impl !UnwindSafe for Backend
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the foreground set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red()
and
green()
, which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg()
:
use yansi::{Paint, Color};
painted.fg(Color::White);
Set foreground color to white using white()
.
use yansi::Paint;
painted.white();
§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self
with the background set to
value
.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red()
and
on_green()
, which have the same functionality but
are pithier.
§Example
Set background color to red using fg()
:
use yansi::{Paint, Color};
painted.bg(Color::Red);
Set background color to red using on_red()
.
use yansi::Paint;
painted.on_red();
§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute
] value
.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold()
and
underline()
, which have the same functionality
but are pithier.
§Example
Make text bold using attr()
:
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);
Make text bold using using bold()
.
use yansi::Paint;
painted.bold();
§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi
[Quirk
] value
.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask()
and
wrap()
, which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk()
:
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);
Enable wrapping using wrap()
.
use yansi::Paint;
painted.wrap();
§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting()
due to conflicts with Vec::clear()
.
The clear()
method will be removed in a future release.§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition
] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted
only when both stdout
and stderr
are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 816 bytes