rust feature

4419 ワード

rust featureは主に条件依存として一定の機能を果たしており、私は主に2つの点を理解している:1.libとして、外部にオプションの機能項目を提供する2.バイナリファイルとして、コンパイルはcargo build--features="*"を通じて実行可能なファイルの体積を縮小することができる.
説明する必要があるのは、コード内のfeatureを開いているすべての場所に属性説明を付けることです.
簡単な例を例にとると、ws−rsにはssl featureもnativessl featureも使用できる2つのfeatureが提供される.ただし、featureを開く場所に対応するコードを追加する必要があります.
impl io::Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result {
        match *self {
            Tcp(ref mut sock) => sock.read(buf),
            #[cfg(any(feature = "ssl", feature = "nativetls"))]
            Tls(TlsStream::Live(ref mut sock)) => sock.read(buf),
            #[cfg(any(feature = "ssl", feature = "nativetls"))]
            Tls(ref mut tls_stream) => {
                trace!("Attempting to read ssl handshake.");
                match replace(tls_stream, TlsStream::Upgrading) {
                    TlsStream::Live(_) | TlsStream::Upgrading => unreachable!(),
                    TlsStream::Handshake {
                        sock,
                        mut negotiating,
                    } => match sock.handshake() {
                        Ok(mut sock) => {
                            trace!("Completed SSL Handshake");
                            let res = sock.read(buf);
                            *tls_stream = TlsStream::Live(sock);
                            res
                        }
                        #[cfg(feature = "ssl")]
                        Err(HandshakeError::SetupFailure(err)) => {
                            Err(io::Error::new(io::ErrorKind::Other, err))
                        }
                        #[cfg(feature = "ssl")]
                        Err(HandshakeError::Failure(mid))
                        | Err(HandshakeError::WouldBlock(mid)) => {
                            if mid.error().code() == SslErrorCode::WANT_READ {
                                negotiating = true;
                            }
                            let err = if let Some(io_error) = mid.error().io_error() {
                                Err(io::Error::new(
                                    io_error.kind(),
                                    format!("{:?}", io_error.get_ref()),
                                ))
                            } else {
                                Err(io::Error::new(
                                    io::ErrorKind::Other,
                                    format!("{}", mid.error()),
                                ))
                            };
                            *tls_stream = TlsStream::Handshake {
                                sock: mid,
                                negotiating,
                            };
                            err
                        }
                        #[cfg(feature = "nativetls")]
                        Err(HandshakeError::WouldBlock(mid)) => {
                            negotiating = true;
                            *tls_stream = TlsStream::Handshake {
                                sock: mid,
                                negotiating: negotiating,
                            };
                            Err(io::Error::new(io::ErrorKind::WouldBlock, "SSL would block"))
                        }
                        #[cfg(feature = "nativetls")]
                        Err(HandshakeError::Failure(err)) => {
                            Err(io::Error::new(io::ErrorKind::Other, format!("{}", err)))
                        }
                    },
                }
            }
        }
    }
}
さらにコンパイル時にはcargo build--features=""とcargo run--features=""も提供され、デフォルトではdefault featureが提供され、すべてのfeatureで使用される依存要件はオプション依存として構成されています.
たとえば、ssl=["openssl"]nativetls=["native-tls"]
オプションの依存度は次のとおりです.
[dependencies.openssl]
optional = true
version = "0.10"

[dependencies.native-tls]
optional = true
version = "0.2"
libがCargo.tomlファイルに格納されている場合、使用例:ryu={version="0.2"、default-features=false}default-features compiletest_を閉じます.rs={version="0.3",features=[「stable」}stable feature+default featureを使用しますか?
cargo run同様:cargo run--features=「openssl」--no-default-features default-featuresは使用せず、手動で閉じる必要があります.