rust feature

rust feature主要作为条件依赖起到一定的功能,我理解主要有两点:
1.作为lib,向外部提供可选的功能项
2.作为二进制文件,可以在编译是通过cargo build --features="*"来缩小可执行文件的体积。

需要说明的是,在代码中所有开启feature的地方都要加上属性说明。

以一个简单的例子为例,在ws-rs中提供了两个feature,既可以使用ssl feature,也可以使用nativessl 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 不使用需手动关闭。

你可能感兴趣的:(rust feature)