如何匹配表示为OsStr的文件扩展名?

时间:2017-02-07 22:16:43

标签: string rust

我正在尝试针对文件扩展名match

let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension() {
    None => "",
    Some(os_str) => match os_str {
        "html" => "text/html",
        "css" => "text/css",
        "js" => "application/javascript",
    },
};

编译器说:

error[E0308]: mismatched types
 --> src/main.rs:6:13
  |
6 |             "html" => "text/html",
  |             ^^^^^^ expected struct `std::ffi::OsStr`, found str
  |
  = note: expected type `&std::ffi::OsStr`
             found type `&'static str`

2 个答案:

答案 0 :(得分:9)

OsStrOsString恰好存在,因为文件名不是 UTF-8。 Rust字符串文字是UTF-8。这意味着你必须处理两种表示之间的转换。

一种解决方案是放弃public class Connection { public void createConnectionForPublishing (final Context context) { //Instantiate the mqtt android client class mqttAndroidClient = new MqttAndroidClient (context.getApplicationContext (), serverUri, clientId); mqttAndroidClient.setCallback (new MqttCallbackExtended () { @Override public void connectComplete(boolean reconnect, String serverURI) { if (reconnect) { System.out.println ("Reconnected to : " + serverURI); } else { System.out.println ("Connected to: " + serverURI); } } @Override public void connectionLost (Throwable cause) { System.out.println ("The Connection was lost."); } @Override public void messageArrived (String topic, final MqttMessage message) throws Exception { System.out.println ("Message received and Arrived"); } @Override public void deliveryComplete (IMqttDeliveryToken token) { System.out.println("Message Delivered"); } }); final MqttConnectOptions mqttConnectOptions = new MqttConnectOptions (); mqttConnectOptions.setMqttVersion (MqttConnectOptions.MQTT_VERSION_3_1_1); mqttConnectOptions.setAutomaticReconnect (true); mqttConnectOptions.setCleanSession (false); try { mqttAndroidClient.connect (mqttConnectOptions, null, new IMqttActionListener () { @Override public void onSuccess (IMqttToken asyncActionToken) { System.out.println ("BROKER CONNECTED"); DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions (); disconnectedBufferOptions.setBufferEnabled (true); disconnectedBufferOptions.setBufferSize (100); disconnectedBufferOptions.setPersistBuffer (false); disconnectedBufferOptions.setDeleteOldestMessages (false); //mqttAndroidClient.setBufferOpts (disconnectedBufferOptions); } @Override public void onFailure (IMqttToken asyncActionToken, Throwable exception) { System.out.println ("Failed to connect to: " + serverUri); } }); } catch (MqttException ex) { ex.printStackTrace (); } } // ... } 并使用if-else语句。有关示例,请参阅Stargateur's answer

您还可以将扩展名转换为字符串。由于扩展名可能不是UTF-8,因此返回另一个match

Option

如果您希望所有案例都使用空字符串作为后备,您可以执行以下操作:

fn main() {
    let file_path = std::path::Path::new("index.html");
    let content_type = match file_path.extension() {
        None => "",
        Some(os_str) => {
            match os_str.to_str() {
                Some("html") => "text/html",
                Some("css") => "text/css",
                Some("js") => "application/javascript",
                _ => panic!("You forgot to specify this case!"),
            }
        }
    };
}

或者,如果您想使用use std::ffi::OsStr; fn main() { let file_path = std::path::Path::new("index.html"); let content_type = match file_path.extension().and_then(OsStr::to_str) { Some("html") => "text/html", Some("css") => "text/css", Some("js") => "application/javascript", _ => "", }; } 作为后备:

None

答案 1 :(得分:7)

您可以对OsStr使用PartialEq<str>特征。

fn main() {
    let file_path = std::path::Path::new("index.html");
    let content_type = match file_path.extension() {
        None => "",
        Some(os_str) => {
            if os_str == "html" {
                "text/html"
            } else if os_str == "css" {
                "text/css"
            } else if os_str == "js" {
                "application/javascript"
            } else {
                ""
            }
        }
    };
    println!("{:?}", content_type);
}