我已经将自己放在rustls's GitHub page上的完整示例上。
现在,我想使用该确切的代码并将其封装在Struct中。
Struct应该负责流的创建(在示例中为tls
)。
此流是最重要的对象,必须将其存储以供以后读取和写入。
我想出了以下结构和实现:
struct Client<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> {
tls: rustls::Stream<'a, S, T>,
}
impl<'a, S: 'a + rustls::Session + ?Sized, T: 'a + Read + Write + ?Sized> Client<'a, S, T> {
fn new(host: &str, port: &str) -> Client<'a, S, T> {
let mut config = rustls::ClientConfig::new();
config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
let dns_name = webpki::DNSNameRef::try_from_ascii_str(host).unwrap();
let mut sess = rustls::ClientSession::new(&Arc::new(config), dns_name);
let mut sock = TcpStream::connect(format!("{}:{}", host, port)).unwrap();
let mut tls = rustls::Stream::new(&mut sess, &mut sock);
Client {
tls
}
}
}
这将导致以下错误:
error[E0308]: mismatched types
--> src\main.rs:27:13
|
16 | impl<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> Client<'a, S, T> {
| - this type parameter
...
27 | tls
| ^^^ expected type parameter `S`, found struct `rustls::client::ClientSession`
|
= note: expected struct `rustls::stream::Stream<'_, S, T>`
found struct `rustls::stream::Stream<'_, rustls::client::ClientSession, std::net::TcpStream>`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
首先,我不知道如何解决此问题。
根据{{3}} rustls::ClientSession
确实实现了特征rustls::Session
,即S
。
第二,我担心生命周期将成为一个问题。
(目前无法确认,因为编译器现在仅抱怨类型不匹配。)
所有这些变量均已创建,据我所知,函数返回后将立即销毁所有这些变量。
意味着sess
和sock
也将被销毁,因为它们没有存储在任何地方,并且tls
上只有&mut
引用(即不存储对象本身)。
我也会像这样存储它们:
struct Client<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> {
session: rustls::ClientSession,
socket: TcpStream,
tls: rustls::Stream<'a, S, T>,
}
(...)
Client {
session: sess,
socket: sock,
tls
}
尽管这不能解决问题,因为tls
现在仍然引用了函数返回时将移动的局部变量(即,再次:指向空指针)。
我该如何解决编译问题?如果生存期成为问题,该如何处理?
此外,存储tls
可能是一个错误的决定吗?
到目前为止,我从Rust
中学到的是“如果很难做到,那可能是错误的!”。