美文网首页
rust feature

rust feature

作者: bradyjoestar | 来源:发表于2019-08-12 21:52 被阅读0次

    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<usize> {
            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

          本文链接:https://www.haomeiwen.com/subject/grwpjctx.html