fn render_header<B: Backend>(f: &mut Frame<'_, B>, app: &mut TuiApp, rect: Rect) {
    let header_block = Block::default()
        .title(format!(" Trippy v{} ", clap::crate_version!()))
        .title_alignment(Alignment::Center)
        .borders(Borders::ALL)
        .border_type(BorderType::Rounded)
        .style(Style::default());
    let now = chrono::Local::now().to_rfc3339_opts(SecondsFormat::Secs, true);
    let clock_span = Spans::from(Span::raw(now));
    let help_span = Spans::from(vec![
        Span::styled("h", Style::default().add_modifier(Modifier::BOLD)),
        Span::raw("elp "),
        Span::styled("q", Style::default().add_modifier(Modifier::BOLD)),
        Span::raw("uit"),
    ]);
    let right_spans = vec![clock_span, help_span];
    let right = Paragraph::new(right_spans)
        .style(Style::default())
        .block(header_block.clone())
        .alignment(Alignment::Right);
    let protocol = &app.tracer_config().protocol;
    let dns = format_dns_method(app.resolver.config().resolve_method);
    let as_info = match app.resolver.config().resolve_method {
        DnsResolveMethod::System => String::from("n/a"),
        DnsResolveMethod::Resolv | DnsResolveMethod::Google | DnsResolveMethod::Cloudflare => {
            if app.tui_config.lookup_as_info {
                String::from("on")
            } else {
                String::from("off")
            }
        }
    };
    let interval = humantime::format_duration(app.tracer_config().min_round_duration);
    let grace = humantime::format_duration(app.tracer_config().grace_duration);
    let first_ttl = app.tracer_config().first_ttl;
    let max_ttl = app.tracer_config().max_ttl;
    let max_hosts = app
        .tui_config
        .max_addrs
        .map_or_else(|| String::from("auto"), |m| m.to_string());
    let left_spans = vec![
        Spans::from(vec![
            Span::styled("Target: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(format!(
                "{} ({})",
                app.tracer_config().target_hostname,
                app.tracer_config().target_addr
            )),
        ]),
        Spans::from(vec![
            Span::styled("Config: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(format!("protocol={} dns={} as-info={} interval={} grace={} start-ttl={} max-ttl={} max-hosts={}",
                              protocol, dns, as_info, interval, grace, first_ttl, max_ttl, max_hosts))]),
        Spans::from(vec![
            Span::styled("Status: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(if let Some(start) = app.frozen_start {
                format!(
                    "Frozen ({})",
                    humantime::format_duration(Duration::from_secs(
                        start.elapsed().unwrap_or_default().as_secs()
                    ))
                )
            } else {
                String::from("Running")
            }),
            Span::raw(format!(
                ", discovered {} hops",
                app.tracer_data().hops().len()
            )),
        ]),
    ];

    let left = Paragraph::new(left_spans)
        .style(Style::default())
        .block(header_block)
        .alignment(Alignment::Left);
    f.render_widget(right, rect);
    f.render_widget(left, rect);
}
/// Render the title, config, target, clock and keyboard controls.
Render the title, config, target, clock and keyboard controls.
Render the title config target clock and keyboard controls .
fn render_header<B: Backend>(f: &mut Frame<'_, B>, app: &mut TuiApp, rect: Rect) {
    let header_block = Block::default()
        .title(format!(" Trippy v{} ", clap::crate_version!()))
        .title_alignment(Alignment::Center)
        .borders(Borders::ALL)
        .border_type(BorderType::Rounded)
        .style(Style::default());
    let now = chrono::Local::now().to_rfc3339_opts(SecondsFormat::Secs, true);
    let clock_span = Spans::from(Span::raw(now));
    let help_span = Spans::from(vec![
        Span::styled("h", Style::default().add_modifier(Modifier::BOLD)),
        Span::raw("elp "),
        Span::styled("q", Style::default().add_modifier(Modifier::BOLD)),
        Span::raw("uit"),
    ]);
    let right_spans = vec![clock_span, help_span];
    let right = Paragraph::new(right_spans)
        .style(Style::default())
        .block(header_block.clone())
        .alignment(Alignment::Right);
    let protocol = &app.tracer_config().protocol;
    let dns = format_dns_method(app.resolver.config().resolve_method);
    let as_info = match app.resolver.config().resolve_method {
        DnsResolveMethod::System => String::from("n/a"),
        DnsResolveMethod::Resolv | DnsResolveMethod::Google | DnsResolveMethod::Cloudflare => {
            if app.tui_config.lookup_as_info {
                String::from("on")
            } else {
                String::from("off")
            }
        }
    };
    let interval = humantime::format_duration(app.tracer_config().min_round_duration);
    let grace = humantime::format_duration(app.tracer_config().grace_duration);
    let first_ttl = app.tracer_config().first_ttl;
    let max_ttl = app.tracer_config().max_ttl;
    let max_hosts = app
        .tui_config
        .max_addrs
        .map_or_else(|| String::from("auto"), |m| m.to_string());
    let left_spans = vec![
        Spans::from(vec![
            Span::styled("Target: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(format!(
                "{} ({})",
                app.tracer_config().target_hostname,
                app.tracer_config().target_addr
            )),
        ]),
        Spans::from(vec![
            Span::styled("Config: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(format!("protocol={} dns={} as-info={} interval={} grace={} start-ttl={} max-ttl={} max-hosts={}",
                              protocol, dns, as_info, interval, grace, first_ttl, max_ttl, max_hosts))]),
        Spans::from(vec![
            Span::styled("Status: ", Style::default().add_modifier(Modifier::BOLD)),
            Span::raw(if let Some(start) = app.frozen_start {
                format!(
                    "Frozen ({})",
                    humantime::format_duration(Duration::from_secs(
                        start.elapsed().unwrap_or_default().as_secs()
                    ))
                )
            } else {
                String::from("Running")
            }),
            Span::raw(format!(
                ", discovered {} hops",
                app.tracer_data().hops().len()
            )),
        ]),
    ];
    let left = Paragraph::new(left_spans)
        .style(Style::default())
        .block(header_block)
        .alignment(Alignment::Left);
    f.render_widget(right, rect);
    f.render_widget(left, rect);
}
fn render_header < B : Backend > ( f : & mut Frame < ' _ , B > , app : & mut TuiApp , rect : Rect ) { let header_block = Block :: default ( ) . title ( format ! ( " " clap crate_version ( ) ) ) . title_alignment ( Alignment :: Center ) . borders ( Borders :: ALL ) . border_type ( BorderType :: Rounded ) . style ( Style :: default ( ) ) ; let now = chrono :: Local :: now ( ) . to_rfc3339_opts ( SecondsFormat :: Secs , true ) ; let clock_span = Spans :: from ( Span :: raw ( now ) ) ; let help_span = Spans :: from ( vec ! [ Span styled ( " " Style default ( ) add_modifier ( Modifier BOLD ) ) Span raw ( " " ) Span styled ( " " Style default ( ) add_modifier ( Modifier BOLD ) ) Span raw ( " " ) ] ) ; let right_spans = vec ! [ clock_span help_span ] ; let right = Paragraph :: new ( right_spans ) . style ( Style :: default ( ) ) . block ( header_block . clone ( ) ) . alignment ( Alignment :: Right ) ; let protocol = & app . tracer_config ( ) . protocol ; let dns = format_dns_method ( app . resolver . config ( ) . resolve_method ) ; let as_info = match app . resolver . config ( ) . resolve_method { DnsResolveMethod :: System => String :: from ( " " ) , DnsResolveMethod :: Resolv | DnsResolveMethod :: Google | DnsResolveMethod :: Cloudflare => { if app . tui_config . lookup_as_info { String :: from ( " " ) } else { String :: from ( " " ) } } } ; let interval = humantime :: format_duration ( app . tracer_config ( ) . min_round_duration ) ; let grace = humantime :: format_duration ( app . tracer_config ( ) . grace_duration ) ; let first_ttl = app . tracer_config ( ) . first_ttl ; let max_ttl = app . tracer_config ( ) . max_ttl ; let max_hosts = app . tui_config . max_addrs . map_or_else ( | | String :: from ( " " ) , | m | m . to_string ( ) ) ; let left_spans = vec ! [ Spans from ( vec [ Span styled ( " " Style default ( ) add_modifier ( Modifier BOLD ) ) Span raw ( format ( " " app tracer_config ( ) target_hostname app tracer_config ( ) target_addr ) ) ] ) Spans from ( vec [ Span styled ( " " Style default ( ) add_modifier ( Modifier BOLD ) ) Span raw ( format ( " " protocol dns as_info interval grace first_ttl max_ttl max_hosts ) ) ] ) Spans from ( vec [ Span styled ( " " Style default ( ) add_modifier ( Modifier BOLD ) ) Span raw ( if let Some ( start ) app frozen_start { format ( " " humantime format_duration ( Duration from_secs ( start elapsed ( ) unwrap_or_default ( ) as_secs ( ) ) ) ) } else { String from ( " " ) } ) Span raw ( format ( " " app tracer_data ( ) hops ( ) len ( ) ) ) ] ) ] ; let left = Paragraph :: new ( left_spans ) . style ( Style :: default ( ) ) . block ( header_block ) . alignment ( Alignment :: Left ) ; f . render_widget ( right , rect ) ; f . render_widget ( left , rect ) ; }
Render the title, config, target, clock and keyboard controls.
Render the title config target clock and keyboard controls .
f
&mut Frame<'_, B>
app
&mut TuiApp
rect
Rect