You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: oidc_service.rs
    path of file: ./repos/ockam/implementations/rust/ockam/ockam_command/src/enroll
    
    the code of the file until where you have to start completion: use async_trait::async_trait;
use std::borrow::Borrow;
use std::io::stdin;

use arboard::Clipboard;
use colorful::Colorful;
use console::Term;
use miette::{miette, IntoDiagnostic};
use reqwest::StatusCode;
use tokio::time::{sleep, Duration};
use tracing::{debug, instrument};

use ockam_api::cloud::enroll::auth0::*;
use ockam_api::enroll::oidc_service::OidcService;

use crate::{
    fmt_err, fmt_heading, fmt_log,
    terminal::{color_email, color_uri},
    CommandGlobalOpts, Result, Terminal, TerminalStream,
};
use crate::{fmt_ok, terminal::OckamColor};

#[async_trait]
pub trait OidcServiceExt {
    /// Retrieve a token by having the user copy and paste a device code in their browser
    async fn get_token_interactively(&self, opts: &CommandGlobalOpts) -> Result<OidcToken>;

    /// Retrieve a token using the device code get a token from the OIDC service
    async fn get_token(&self, opts: &CommandGlobalOpts) -> Result<OidcToken>;

    async fn wait_for_email_verification(
        &self,
        token: &OidcToken,
        terminal: Option<&Terminal<TerminalStream<Term>>>,
    ) -> Result<UserInfo>;

    /// Open a browser from one of the URIs returned by a device code
    //
    
    async fn get_token_interactively(&self, opts: &CommandGlobalOpts) -> Result<OidcToken> {
        let device_code = self.device_code().await?;

        // On Linux, the clipboard is cleared when the record goes out of scope, so
        // declare it up here, in the scope that bounds the entire interaction
        let mut clipboard;

        // If the terminal is quiet, write only the code at stdout so it can be processed
        if opts.terminal.is_quiet() {
            opts.terminal
                .clone()
                .stdout()
                .plain(device_code.user_code.to_string())
                .write_line()?;
        }
        // Otherwise, write the instructions at stderr as normal
        else {
            clipboard = Clipboard::new();
            let otc_string = clipboard
                .as_mut()
                .ok()
                .and_then(|clip| clip.set_text(device_code.user_code.to_string()).ok())
                .map_or(
                    fmt_heading!(
                        "Please copy this one-time code: {}",
                        format!(" {} ", device_code.user_code).bg_white().black()
                    ),
                    |_| {
                        fmt_heading!(
                            "Your one-time code: {} has been {}.",
                            format!(" {} ", device_code.user_code).bg_white().black(),
                            "copied to the clipboard".color(OckamColor::Success.color())
                        )
                    },
                );

            opts.terminal
                .write_line(&fmt_heading!(
                    "Let's associate your Ockam Identity with an Orchestrator account."
                ))?
                .write_line(&otc_string)?
                .write(fmt_log!(
                    "Please press {} to open {} in your browser.",
                    " ENTER â†µ ".bg_white().black().blink(),
                    color_uri(&device_code.verification_uri)
                ))?;

            let mut input = String::new();
            match stdin().read_line(&mut input) {
                Ok(_) => {
                    opts.terminal
                        .write_line(&fmt_log!(""))?
                        .write_line(&fmt_log!(
                            "Opening {}, in your browser, to begin activating this machine...",
                            color_uri(&device_code.verification_uri)
                        ))?;
                }
                Err(_e) => {
                    return Err(miette!(
                        "Couldn't read user input or enter keypress from stdin"
                    ))?;
                }
            }
        }

        // Request device activation
        // Note that we try to open the verification uri **without** the code.
        // After the code is entered, if the user closes the tab (because they
        // want to open it on another browser, for example), the uri gets
        // invalidated and the user would have to restart the process (i.e.
        // rerun the command).
        let uri = device_code.verification_uri.to_string();
        self.get_token_from_browser(opts, device_code, uri).await
    }