/// wait_for_match attempts to find a target matching "matcher". If no
/// matcher is provided, either the default target is matched, or, if there
/// is no default a single target is returned iff it is the only target in
/// the collection. If there is neither a matcher or a defualt, and there are
/// several targets in the collection when the query starts, a
/// DaemonError::TargetAmbiguous error is returned. The matcher is converted to a
/// TargetQuery for matching, and follows the TargetQuery semantics.
wait_for_match attempts to find a target matching "matcher". If no
matcher is provided, either the default target is matched, or, if there
is no default a single target is returned iff it is the only target in
the collection. If there is neither a matcher or a defualt, and there are
several targets in the collection when the query starts, a
DaemonError::TargetAmbiguous error is returned. The matcher is converted to a
TargetQuery for matching, and follows the TargetQuery semantics.
wait_for_match attempts to find a target matching " matcher " . If no matcher is provided either the default target is matched or if there is no default a single target is returned iff it is the only target in the collection . If there is neither a matcher or a defualt and there are several targets in the collection when the query starts a DaemonError :: TargetAmbiguous error is returned . The matcher is converted to a TargetQuery for matching and follows the TargetQuery semantics .
pub async fn wait_for_match(&self, matcher: Option<String>) -> Result<Target, DaemonError> {
        // If there's nothing to match against, unblock on the first target.
        let target_query = TargetQuery::from(matcher.clone());
        // If there is no matcher, and there are already multiple targets in the
        // target collection, we know that the target is ambiguous and thus
        // produce an actionable error to the user.
        if let TargetQuery::First = target_query {
            // PERFORMANCE: it's possible to avoid the discarded clones here, with more work.
            // This is a stop-gap UX check. The other option is to
            // just display disconnected targets in `ffx target list` to make it
            // clear that an ambiguous target error is about having more than
            // one target in the cache rather than giving an ambiguous target
            // error around targets that cannot be displayed in the frontend.
            let targets = &self.inner.read().await.named;
            let targets =
                futures::future::join_all(
                    targets
                        .values()
                        .map(|t| async move {
                            t.inner.state.lock().await.connection_state.is_connected()
                        })
                        .collect::<Vec<_>>(),
                )
                .await;
            let targets = targets.iter().filter(|&&t| t).collect::<Vec<_>>();
            if targets.len() > 1 {
                return Err(DaemonError::TargetAmbiguous);
            }
        }
        // Infinite timeout here is fine, as the client dropping connection
        // will lead to this being cleaned up eventually. It is the client's
        // responsibility to determine their respective timeout(s).
        self.events
            .read()
            .await
            .as_ref()
            .expect("target event queue must be initialized by now")
            .wait_for(None, move |e| {
                if let DaemonEvent::NewTarget(ref target_info) = e {
                    target_query.match_info(target_info)
                } else {
                    false
                }
            })
            .await
            .map_err(|e| {
                log::warn!("{}", e);
                DaemonError::TargetCacheError
            })?;
        // TODO(awdavies): It's possible something might happen between the new
        // target event and now, so it would make sense to give the
        // user some information on what happened: likely something
        // to do with the target suddenly being forced out of the cache
        // (this isn't a problem yet, but will be once more advanced
        // lifetime tracking is implemented). If a name isn't specified it's
        // possible a secondary/tertiary target showed up, and those cases are
        // handled here.
        self.get_connected(matcher).await.ok_or(DaemonError::TargetNotFound)
    }
pub async fn wait_for_match ( & self , matcher : Option < String > ) -> Result < Target , DaemonError > { // If there's nothing to match against, unblock on the first target. let target_query = TargetQuery :: from ( matcher . clone ( ) ) ; // If there is no matcher, and there are already multiple targets in the // target collection, we know that the target is ambiguous and thus // produce an actionable error to the user. if let TargetQuery :: First = target_query { // PERFORMANCE: it's possible to avoid the discarded clones here, with more work. // This is a stop-gap UX check. The other option is to // just display disconnected targets in `ffx target list` to make it // clear that an ambiguous target error is about having more than // one target in the cache rather than giving an ambiguous target // error around targets that cannot be displayed in the frontend. let targets = & self . inner . read ( ) . await . named ; let targets = futures :: future :: join_all ( targets . values ( ) . map ( | t | async move { t . inner . state . lock ( ) . await . connection_state . is_connected ( ) } ) . collect :: < Vec < _ > > ( ) , ) . await ; let targets = targets . iter ( ) . filter ( | & & t | t ) . collect :: < Vec < _ > > ( ) ; if targets . len ( ) > 1 { return Err ( DaemonError :: TargetAmbiguous ) ; } } // Infinite timeout here is fine, as the client dropping connection // will lead to this being cleaned up eventually. It is the client's // responsibility to determine their respective timeout(s). self . events . read ( ) . await . as_ref ( ) . expect ( " " ) . wait_for ( None , move | e | { if let DaemonEvent :: NewTarget ( ref target_info ) = e { target_query . match_info ( target_info ) } else { false } } ) . await . map_err ( | e | { log :: warn ! ( " " e ) ; DaemonError :: TargetCacheError } ) ? ; // TODO(awdavies): It's possible something might happen between the new // target event and now, so it would make sense to give the // user some information on what happened: likely something // to do with the target suddenly being forced out of the cache // (this isn't a problem yet, but will be once more advanced // lifetime tracking is implemented). If a name isn't specified it's // possible a secondary/tertiary target showed up, and those cases are // handled here. self . get_connected ( matcher ) . await . ok_or ( DaemonError :: TargetNotFound ) }
wait_for_match attempts to find a target matching "matcher".
wait_for_match attempts to find a target matching " matcher " .
&self
matcher
Option<String>