pub struct Client { /* private fields */ }Expand description
Main client for interacting with EdgeFirst Studio Server.
The EdgeFirst Client handles the connection to the EdgeFirst Studio Server and manages authentication, RPC calls, and data operations. It provides methods for managing projects, datasets, experiments, training sessions, and various utility functions for data processing.
The client supports multiple authentication methods and can work with both SaaS and self-hosted EdgeFirst Studio instances.
§Features
- Authentication: Token-based authentication with automatic persistence
- Dataset Management: Upload, download, and manipulate datasets
- Project Operations: Create and manage projects and experiments
- Training & Validation: Submit and monitor ML training jobs
- Data Integration: Convert between EdgeFirst datasets and popular formats
- Progress Tracking: Real-time progress updates for long-running operations
§Examples
use edgefirst_client::{Client, DatasetID};
use std::str::FromStr;
// Create a new client and authenticate
let mut client = Client::new()?;
let client = client
.with_login("your-email@example.com", "password")
.await?;
// Or use an existing token
let base_client = Client::new()?;
let client = base_client.with_token("your-token-here")?;
// Get organization and projects
let org = client.organization().await?;
let projects = client.projects(None).await?;
// Work with datasets
let dataset_id = DatasetID::from_str("ds-abc123")?;
let dataset = client.dataset(dataset_id).await?;Implementations§
Source§impl Client
impl Client
Sourcepub fn new() -> Result<Self, Error>
pub fn new() -> Result<Self, Error>
Create a new unauthenticated client with the default saas server. To
connect to a different server use the with_server method or with the
with_token method to create a client with a token which includes the
server instance name (test, stage, saas).
This client is created without a token and will need to login before
using any methods that require authentication. Use the with_token
method to create a client with a token.
Sourcepub fn with_server(&self, server: &str) -> Result<Self, Error>
pub fn with_server(&self, server: &str) -> Result<Self, Error>
Returns a new client connected to the specified server instance. If a token is already set in the client then it will be dropped as the token is specific to the server instance.
Sourcepub async fn with_login(
&self,
username: &str,
password: &str,
) -> Result<Self, Error>
pub async fn with_login( &self, username: &str, password: &str, ) -> Result<Self, Error>
Returns a new client authenticated with the provided username and password.
Sourcepub fn with_token_path(&self, token_path: Option<&Path>) -> Result<Self, Error>
pub fn with_token_path(&self, token_path: Option<&Path>) -> Result<Self, Error>
Returns a new client which will load and save the token to the specified path.
Sourcepub fn with_token(&self, token: &str) -> Result<Self, Error>
pub fn with_token(&self, token: &str) -> Result<Self, Error>
Returns a new client authenticated with the provided token.
pub async fn save_token(&self) -> Result<(), Error>
Sourcepub async fn version(&self) -> Result<String, Error>
pub async fn version(&self) -> Result<String, Error>
Return the version of the EdgeFirst Studio server for the current client connection.
Sourcepub async fn logout(&self) -> Result<(), Error>
pub async fn logout(&self) -> Result<(), Error>
Clear the token used to authenticate the client with the server. If an optional path was provided when creating the client, the token file will also be cleared.
Sourcepub async fn token(&self) -> String
pub async fn token(&self) -> String
Return the token used to authenticate the client with the server. When logging into the server using a username and password, the token is returned by the server and stored in the client for future interactions.
Sourcepub async fn verify_token(&self) -> Result<(), Error>
pub async fn verify_token(&self) -> Result<(), Error>
Verify the token used to authenticate the client with the server. This method is used to ensure that the token is still valid and has not expired. If the token is invalid, the server will return an error and the client will need to login again.
Sourcepub async fn renew_token(&self) -> Result<(), Error>
pub async fn renew_token(&self) -> Result<(), Error>
Renew the token used to authenticate the client with the server. This method is used to refresh the token before it expires. If the token has already expired, the server will return an error and the client will need to login again.
Sourcepub fn url(&self) -> &str
pub fn url(&self) -> &str
Returns the URL of the EdgeFirst Studio server for the current client.
Sourcepub async fn username(&self) -> Result<String, Error>
pub async fn username(&self) -> Result<String, Error>
Returns the username associated with the current token.
Sourcepub async fn token_expiration(&self) -> Result<DateTime<Utc>, Error>
pub async fn token_expiration(&self) -> Result<DateTime<Utc>, Error>
Returns the expiration time for the current token.
Sourcepub async fn organization(&self) -> Result<Organization, Error>
pub async fn organization(&self) -> Result<Organization, Error>
Returns the organization information for the current user.
Sourcepub async fn projects(&self, name: Option<&str>) -> Result<Vec<Project>, Error>
pub async fn projects(&self, name: Option<&str>) -> Result<Vec<Project>, Error>
Returns a list of projects available to the user. The projects are returned as a vector of Project objects. If a name filter is provided, only projects matching the filter are returned.
Projects are the top-level organizational unit in EdgeFirst Studio. Projects contain datasets, trainers, and trainer sessions. Projects are used to group related datasets and trainers together.
Sourcepub async fn project(&self, project_id: ProjectID) -> Result<Project, Error>
pub async fn project(&self, project_id: ProjectID) -> Result<Project, Error>
Return the project with the specified project ID. If the project does not exist, an error is returned.
Sourcepub async fn datasets(
&self,
project_id: ProjectID,
name: Option<&str>,
) -> Result<Vec<Dataset>, Error>
pub async fn datasets( &self, project_id: ProjectID, name: Option<&str>, ) -> Result<Vec<Dataset>, Error>
Returns a list of datasets available to the user. The datasets are returned as a vector of Dataset objects. If a name filter is provided, only datasets matching the filter are returned.
Sourcepub async fn dataset(&self, dataset_id: DatasetID) -> Result<Dataset, Error>
pub async fn dataset(&self, dataset_id: DatasetID) -> Result<Dataset, Error>
Return the dataset with the specified dataset ID. If the dataset does not exist, an error is returned.
Sourcepub async fn labels(&self, dataset_id: DatasetID) -> Result<Vec<Label>, Error>
pub async fn labels(&self, dataset_id: DatasetID) -> Result<Vec<Label>, Error>
Lists the labels for the specified dataset.
Sourcepub async fn add_label(
&self,
dataset_id: DatasetID,
name: &str,
) -> Result<(), Error>
pub async fn add_label( &self, dataset_id: DatasetID, name: &str, ) -> Result<(), Error>
Add a new label to the dataset with the specified name.
Sourcepub async fn remove_label(&self, label_id: u64) -> Result<(), Error>
pub async fn remove_label(&self, label_id: u64) -> Result<(), Error>
Removes the label with the specified ID from the dataset. Label IDs are globally unique so the dataset_id is not required.
Sourcepub async fn create_dataset(
&self,
project_id: &str,
name: &str,
description: Option<&str>,
) -> Result<DatasetID, Error>
pub async fn create_dataset( &self, project_id: &str, name: &str, description: Option<&str>, ) -> Result<DatasetID, Error>
Sourcepub async fn update_label(&self, label: &Label) -> Result<(), Error>
pub async fn update_label(&self, label: &Label) -> Result<(), Error>
Updates the label with the specified ID to have the new name or index. Label IDs cannot be changed. Label IDs are globally unique so the dataset_id is not required.
pub async fn download_dataset( &self, dataset_id: DatasetID, groups: &[String], file_types: &[FileType], output: PathBuf, progress: Option<Sender<Progress>>, ) -> Result<(), Error>
Sourcepub async fn annotation_sets(
&self,
dataset_id: DatasetID,
) -> Result<Vec<AnnotationSet>, Error>
pub async fn annotation_sets( &self, dataset_id: DatasetID, ) -> Result<Vec<AnnotationSet>, Error>
List available annotation sets for the specified dataset.
Sourcepub async fn create_annotation_set(
&self,
dataset_id: DatasetID,
name: &str,
description: Option<&str>,
) -> Result<AnnotationSetID, Error>
pub async fn create_annotation_set( &self, dataset_id: DatasetID, name: &str, description: Option<&str>, ) -> Result<AnnotationSetID, Error>
Create a new annotation set for the specified dataset.
§Arguments
dataset_id- The ID of the dataset to create the annotation set inname- The name of the new annotation setdescription- Optional description for the annotation set
§Returns
Returns the annotation set ID of the newly created annotation set.
Sourcepub async fn delete_annotation_set(
&self,
annotation_set_id: AnnotationSetID,
) -> Result<(), Error>
pub async fn delete_annotation_set( &self, annotation_set_id: AnnotationSetID, ) -> Result<(), Error>
Sourcepub async fn annotation_set(
&self,
annotation_set_id: AnnotationSetID,
) -> Result<AnnotationSet, Error>
pub async fn annotation_set( &self, annotation_set_id: AnnotationSetID, ) -> Result<AnnotationSet, Error>
Retrieve the annotation set with the specified ID.
Sourcepub async fn annotations(
&self,
annotation_set_id: AnnotationSetID,
groups: &[String],
annotation_types: &[AnnotationType],
progress: Option<Sender<Progress>>,
) -> Result<Vec<Annotation>, Error>
pub async fn annotations( &self, annotation_set_id: AnnotationSetID, groups: &[String], annotation_types: &[AnnotationType], progress: Option<Sender<Progress>>, ) -> Result<Vec<Annotation>, Error>
Get the annotations for the specified annotation set with the requested annotation types. The annotation types are used to filter the annotations returned. The groups parameter is used to filter for dataset groups (train, val, test). Images which do not have any annotations are also included in the result as long as they are in the requested groups (when specified).
The result is a vector of Annotations objects which contain the full dataset along with the annotations for the specified types.
To get the annotations as a DataFrame, use the annotations_dataframe
method instead.
pub async fn samples_count( &self, dataset_id: DatasetID, annotation_set_id: Option<AnnotationSetID>, annotation_types: &[AnnotationType], groups: &[String], types: &[FileType], ) -> Result<SamplesCountResult, Error>
pub async fn samples( &self, dataset_id: DatasetID, annotation_set_id: Option<AnnotationSetID>, annotation_types: &[AnnotationType], groups: &[String], types: &[FileType], progress: Option<Sender<Progress>>, ) -> Result<Vec<Sample>, Error>
Sourcepub async fn populate_samples(
&self,
dataset_id: DatasetID,
annotation_set_id: Option<AnnotationSetID>,
samples: Vec<Sample>,
progress: Option<Sender<Progress>>,
) -> Result<Vec<SamplesPopulateResult>, Error>
pub async fn populate_samples( &self, dataset_id: DatasetID, annotation_set_id: Option<AnnotationSetID>, samples: Vec<Sample>, progress: Option<Sender<Progress>>, ) -> Result<Vec<SamplesPopulateResult>, Error>
Populates (imports) samples into a dataset using the samples.populate
API.
This method creates new samples in the specified dataset, optionally
with annotations and sensor data files. For each sample, the files
field is checked for local file paths. If a filename is a valid path
to an existing file, the file will be automatically uploaded to S3
using presigned URLs returned by the server. The filename in the
request is replaced with the basename (path removed) before sending
to the server.
§Important Notes
annotation_set_idis REQUIRED when importing samples with annotations. Without it, the server will accept the request but will not save the annotation data. UseClient::annotation_setsto query available annotation sets for a dataset, or create a new one via the Studio UI.- Box2d coordinates must be normalized (0.0-1.0 range) for bounding
boxes. Divide pixel coordinates by image width/height before creating
Box2dannotations. - Files are uploaded automatically when the filename is a valid local path. The method will replace the full path with just the basename before sending to the server.
- Image dimensions are extracted automatically for image files using
the
imagesizecrate. The width/height are sent to the server, but note that the server currently doesn’t return these fields when fetching samples back. - UUIDs are generated automatically if not provided. If you need
deterministic UUIDs, set
sample.uuidexplicitly before calling. Note that the server doesn’t currently return UUIDs in sample queries.
§Arguments
dataset_id- The ID of the dataset to populateannotation_set_id- Required if samples contain annotations, otherwise they will be ignored. Query withClient::annotation_sets.samples- Vector of samples to import with metadata and file references. For files, use the full local path - it will be uploaded automatically. UUIDs and image dimensions will be auto-generated/extracted if not provided.
§Returns
Returns the API result with sample UUIDs and upload status.
§Example
use edgefirst_client::{Annotation, Box2d, Client, DatasetID, Sample, SampleFile};
// Query available annotation sets for the dataset
let annotation_sets = client.annotation_sets(dataset_id).await?;
let annotation_set_id = annotation_sets
.first()
.ok_or_else(|| {
edgefirst_client::Error::InvalidParameters("No annotation sets found".to_string())
})?
.id();
// Create sample with annotation (UUID will be auto-generated)
let mut sample = Sample::new();
sample.width = Some(1920);
sample.height = Some(1080);
sample.group = Some("train".to_string());
// Add file - use full path to local file, it will be uploaded automatically
sample.files = vec![SampleFile::with_filename(
"image".to_string(),
"/path/to/image.jpg".to_string(),
)];
// Add bounding box annotation with NORMALIZED coordinates (0.0-1.0)
let mut annotation = Annotation::new();
annotation.set_label(Some("person".to_string()));
// Normalize pixel coordinates by dividing by image dimensions
let bbox = Box2d::new(0.5, 0.5, 0.25, 0.25); // (x, y, w, h) normalized
annotation.set_box2d(Some(bbox));
sample.annotations = vec![annotation];
// Populate with annotation_set_id (REQUIRED for annotations)
let result = client
.populate_samples(dataset_id, Some(annotation_set_id), vec![sample], None)
.await?;pub async fn download(&self, url: &str) -> Result<Vec<u8>, Error>
Sourcepub async fn annotations_dataframe(
&self,
annotation_set_id: AnnotationSetID,
groups: &[String],
types: &[AnnotationType],
progress: Option<Sender<Progress>>,
) -> Result<DataFrame, Error>
pub async fn annotations_dataframe( &self, annotation_set_id: AnnotationSetID, groups: &[String], types: &[AnnotationType], progress: Option<Sender<Progress>>, ) -> Result<DataFrame, Error>
Get the AnnotationGroup for the specified annotation set with the requested annotation types. The annotation type is used to filter the annotations returned. Images which do not have any annotations are included in the result.
The result is a DataFrame following the EdgeFirst Dataset Format definition.
To get the annotations as a vector of AnnotationGroup objects, use the
annotations method instead.
Sourcepub async fn snapshots(
&self,
name: Option<&str>,
) -> Result<Vec<Snapshot>, Error>
pub async fn snapshots( &self, name: Option<&str>, ) -> Result<Vec<Snapshot>, Error>
List available snapshots. If a name is provided, only snapshots containing that name are returned.
Sourcepub async fn snapshot(&self, snapshot_id: SnapshotID) -> Result<Snapshot, Error>
pub async fn snapshot(&self, snapshot_id: SnapshotID) -> Result<Snapshot, Error>
Get the snapshot with the specified id.
Sourcepub async fn create_snapshot(
&self,
path: &str,
progress: Option<Sender<Progress>>,
) -> Result<Snapshot, Error>
pub async fn create_snapshot( &self, path: &str, progress: Option<Sender<Progress>>, ) -> Result<Snapshot, Error>
Create a new snapshot from the file at the specified path. If the path is a directory then all the files in the directory are uploaded. The snapshot name will be the specified path, either file or directory.
The progress callback can be used to monitor the progress of the upload over a watch channel.
Sourcepub async fn download_snapshot(
&self,
snapshot_id: SnapshotID,
output: PathBuf,
progress: Option<Sender<Progress>>,
) -> Result<(), Error>
pub async fn download_snapshot( &self, snapshot_id: SnapshotID, output: PathBuf, progress: Option<Sender<Progress>>, ) -> Result<(), Error>
Downloads a snapshot from the server. The snapshot could be a single file or a directory of files. The snapshot is downloaded to the specified path. A progress callback can be provided to monitor the progress of the download over a watch channel.
Sourcepub async fn restore_snapshot(
&self,
project_id: ProjectID,
snapshot_id: SnapshotID,
topics: &[String],
autolabel: &[String],
autodepth: bool,
dataset_name: Option<&str>,
dataset_description: Option<&str>,
) -> Result<SnapshotRestoreResult, Error>
pub async fn restore_snapshot( &self, project_id: ProjectID, snapshot_id: SnapshotID, topics: &[String], autolabel: &[String], autodepth: bool, dataset_name: Option<&str>, dataset_description: Option<&str>, ) -> Result<SnapshotRestoreResult, Error>
The snapshot restore method is used to restore a snapshot to the server. The restore method can perform a few different operations depending on the snapshot type.
The auto-annotation workflow is used to automatically annotate the dataset with 2D masks and boxes using the labels within the autolabel list. If autolabel is empty then the auto-annotation workflow is not used. If the MCAP includes radar or LiDAR data then the auto-annotation workflow will also generate 3D bounding boxes for detected objects.
The autodepth flag is used to determine if a depthmap should be automatically generated for the dataset, this will currently only work accurately for Maivin or Raivin cameras.
Sourcepub async fn experiments(
&self,
project_id: ProjectID,
name: Option<&str>,
) -> Result<Vec<Experiment>, Error>
pub async fn experiments( &self, project_id: ProjectID, name: Option<&str>, ) -> Result<Vec<Experiment>, Error>
Returns a list of experiments available to the user. The experiments are returned as a vector of Experiment objects. If name is provided then only experiments containing this string are returned.
Experiments provide a method of organizing training and validation
sessions together and are akin to an Experiment in MLFlow terminology.
Each experiment can have multiple trainer sessions associated with it,
these would be akin to runs in MLFlow terminology.
Sourcepub async fn experiment(
&self,
experiment_id: ExperimentID,
) -> Result<Experiment, Error>
pub async fn experiment( &self, experiment_id: ExperimentID, ) -> Result<Experiment, Error>
Return the experiment with the specified experiment ID. If the experiment does not exist, an error is returned.
Sourcepub async fn training_sessions(
&self,
experiment_id: ExperimentID,
name: Option<&str>,
) -> Result<Vec<TrainingSession>, Error>
pub async fn training_sessions( &self, experiment_id: ExperimentID, name: Option<&str>, ) -> Result<Vec<TrainingSession>, Error>
Returns a list of trainer sessions available to the user. The trainer sessions are returned as a vector of TrainingSession objects. If name is provided then only trainer sessions containing this string are returned.
Trainer sessions are akin to runs in MLFlow terminology. These represent an actual training session which will produce metrics and model artifacts.
Sourcepub async fn training_session(
&self,
session_id: TrainingSessionID,
) -> Result<TrainingSession, Error>
pub async fn training_session( &self, session_id: TrainingSessionID, ) -> Result<TrainingSession, Error>
Return the trainer session with the specified trainer session ID. If the trainer session does not exist, an error is returned.
Sourcepub async fn validation_sessions(
&self,
project_id: ProjectID,
) -> Result<Vec<ValidationSession>, Error>
pub async fn validation_sessions( &self, project_id: ProjectID, ) -> Result<Vec<ValidationSession>, Error>
List validation sessions for the given project.
Sourcepub async fn validation_session(
&self,
session_id: ValidationSessionID,
) -> Result<ValidationSession, Error>
pub async fn validation_session( &self, session_id: ValidationSessionID, ) -> Result<ValidationSession, Error>
Retrieve a specific validation session.
Sourcepub async fn artifacts(
&self,
training_session_id: TrainingSessionID,
) -> Result<Vec<Artifact>, Error>
pub async fn artifacts( &self, training_session_id: TrainingSessionID, ) -> Result<Vec<Artifact>, Error>
List the artifacts for the specified trainer session. The artifacts are returned as a vector of strings.
Sourcepub async fn download_artifact(
&self,
training_session_id: TrainingSessionID,
modelname: &str,
filename: Option<PathBuf>,
progress: Option<Sender<Progress>>,
) -> Result<(), Error>
pub async fn download_artifact( &self, training_session_id: TrainingSessionID, modelname: &str, filename: Option<PathBuf>, progress: Option<Sender<Progress>>, ) -> Result<(), Error>
Download the model artifact for the specified trainer session to the specified file path, if path is not provided it will be downloaded to the current directory with the same filename. A progress callback can be provided to monitor the progress of the download over a watch channel.
Sourcepub async fn download_checkpoint(
&self,
training_session_id: TrainingSessionID,
checkpoint: &str,
filename: Option<PathBuf>,
progress: Option<Sender<Progress>>,
) -> Result<(), Error>
pub async fn download_checkpoint( &self, training_session_id: TrainingSessionID, checkpoint: &str, filename: Option<PathBuf>, progress: Option<Sender<Progress>>, ) -> Result<(), Error>
Download the model checkpoint associated with the specified trainer session to the specified file path, if path is not provided it will be downloaded to the current directory with the same filename. A progress callback can be provided to monitor the progress of the download over a watch channel.
There is no API for listing checkpoints it is expected that trainers are aware of possible checkpoints and their names within the checkpoint folder on the server.
Sourcepub async fn tasks(
&self,
name: Option<&str>,
workflow: Option<&str>,
status: Option<&str>,
manager: Option<&str>,
) -> Result<Vec<Task>, Error>
pub async fn tasks( &self, name: Option<&str>, workflow: Option<&str>, status: Option<&str>, manager: Option<&str>, ) -> Result<Vec<Task>, Error>
Return a list of tasks for the current user.
Sourcepub async fn task_info(&self, task_id: TaskID) -> Result<TaskInfo, Error>
pub async fn task_info(&self, task_id: TaskID) -> Result<TaskInfo, Error>
Retrieve the task information and status.
Sourcepub async fn task_status(
&self,
task_id: TaskID,
status: &str,
) -> Result<Task, Error>
pub async fn task_status( &self, task_id: TaskID, status: &str, ) -> Result<Task, Error>
Updates the tasks status.
Sourcepub async fn set_stages(
&self,
task_id: TaskID,
stages: &[(&str, &str)],
) -> Result<(), Error>
pub async fn set_stages( &self, task_id: TaskID, stages: &[(&str, &str)], ) -> Result<(), Error>
Defines the stages for the task. The stages are defined as a mapping from stage names to their descriptions. Once stages are defined their status can be updated using the update_stage method.
Sourcepub async fn update_stage(
&self,
task_id: TaskID,
stage: &str,
status: &str,
message: &str,
percentage: u8,
) -> Result<(), Error>
pub async fn update_stage( &self, task_id: TaskID, stage: &str, status: &str, message: &str, percentage: u8, ) -> Result<(), Error>
Updates the progress of the task for the provided stage and status information.
Sourcepub async fn fetch(&self, query: &str) -> Result<Vec<u8>, Error>
pub async fn fetch(&self, query: &str) -> Result<Vec<u8>, Error>
Raw fetch from the Studio server is used for downloading files.
Sourcepub async fn post_multipart(
&self,
method: &str,
form: Form,
) -> Result<String, Error>
pub async fn post_multipart( &self, method: &str, form: Form, ) -> Result<String, Error>
Sends a multipart post request to the server. This is used by the upload and download APIs which do not use JSON-RPC but instead transfer files using multipart/form-data.
Sourcepub async fn rpc<Params, RpcResult>(
&self,
method: String,
params: Option<Params>,
) -> Result<RpcResult, Error>where
Params: Serialize,
RpcResult: DeserializeOwned,
pub async fn rpc<Params, RpcResult>(
&self,
method: String,
params: Option<Params>,
) -> Result<RpcResult, Error>where
Params: Serialize,
RpcResult: DeserializeOwned,
Send a JSON-RPC request to the server. The method is the name of the method to call on the server. The params are the parameters to pass to the method. The method and params are serialized into a JSON-RPC request and sent to the server. The response is deserialized into the specified type and returned to the caller.
NOTE: This API would generally not be called directly and instead users should use the higher-level methods provided by the client.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Client
impl !RefUnwindSafe for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl !UnwindSafe for Client
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§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§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