1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use xwt_core::prelude::*;

#[derive(Debug, thiserror::Error)]
pub enum Error<Endpoint>
where
    Endpoint: xwt_core::EndpointConnect + std::fmt::Debug,
    Endpoint::Connecting: std::fmt::Debug,
    EndpointConnectConnectionFor<Endpoint>: xwt_core::OpenBiStream + std::fmt::Debug,
{
    Connect(xwt_error::Connect<Endpoint>),
    Open(xwt_error::OpenBi<EndpointConnectConnectionFor<Endpoint>>),
    Send(WriteErrorFor<SendStreamFor<EndpointConnectConnectionFor<Endpoint>>>),
    Recv(ReadErrorFor<RecvStreamFor<EndpointConnectConnectionFor<Endpoint>>>),
    NoResponse,
    BadData(Vec<u8>),
}

pub async fn run<Endpoint>(endpoint: Endpoint) -> Result<(), Error<Endpoint>>
where
    Endpoint: xwt_core::EndpointConnect + std::fmt::Debug,
    Endpoint::Connecting: std::fmt::Debug,
    EndpointConnectConnectionFor<Endpoint>: xwt_core::OpenBiStream + std::fmt::Debug,
{
    let connection = crate::utils::connect(endpoint, "https://echo.webtransport.day")
        .await
        .map_err(Error::Connect)?;

    let (mut send_stream, mut recv_stream) = crate::utils::open_bi(connection)
        .await
        .map_err(Error::Open)?;

    let mut to_write = &b"hello"[..];
    loop {
        let written = send_stream.write(to_write).await.map_err(Error::Send)?;
        to_write = &to_write[written..];
        if to_write.is_empty() {
            break;
        }
    }

    let mut read_buf = vec![0u8; 2];

    let Some(read) = recv_stream
        .read(&mut read_buf[..])
        .await
        .map_err(Error::Recv)?
    else {
        return Err(Error::NoResponse);
    };
    read_buf.truncate(read);

    if read_buf != b"he" {
        return Err(Error::BadData(read_buf));
    }

    let Some(read) = recv_stream
        .read(&mut read_buf[..])
        .await
        .map_err(Error::Recv)?
    else {
        return Err(Error::NoResponse);
    };
    read_buf.truncate(read);

    if read_buf != b"ll" {
        return Err(Error::BadData(read_buf));
    }

    let Some(read) = recv_stream
        .read(&mut read_buf[..])
        .await
        .map_err(Error::Recv)?
    else {
        return Err(Error::NoResponse);
    };
    read_buf.truncate(read);

    if read_buf != b"o" {
        return Err(Error::BadData(read_buf));
    }

    Ok(())
}