Repository: lapce/lapce
File: lapce-proxy/src/lsp.rs (Rust)

Code before:
        let option = match option {
            Some(val) => val,
            None => {
                return vals;
            }
        };

        let binary = match option["binary"].as_object() {
            Some(binary) => binary,
            None => return vals,
        };

        let option = match binary.get("binary_args") {
            Some(binary_args) => binary_args,
            None => return vals,
        };

        let option = if let Some(option) = option.as_array() {
            option
        } else {
            println!("binary_args value should be of type [String].");
            return vals;
        };

        for val in option {
            vals.push(String::from(val.as_str().unwrap()));
        }

        return vals;
    }

    pub fn new_buffer(
        &self,
        buffer_id: &BufferId,
        path: &str,
        language_id: &str,
        text: String,
    ) {
        let document_uri = Url::from_file_path(path).unwrap();
        if let Some(client) = self.clients.get(language_id) {
            client.send_did_open(buffer_id, document_uri, language_id, text);
        }
    }

    pub fn save_buffer(&self, buffer: &Buffer) {
        if let Some(client) = self.clients.get(&buffer.language_id) {
            let uri = client.get_uri(buffer);
            client.send_did_save(uri);
        }
    }


Review comment (suggestion):
This might be much nicer as `option.iter().map(Value::as_str).map(Option::unwrap).(ToString::to_string).collect::<Vec<_>>()` or something like that, but my main issue is the `String::from` here, which just smells weird on a `str`.

You might not even need to specify the type in `collect`, I don't know.

Code after:
        &mut self,
        option: Option<Value>,
    ) -> Option<Vec<String>> {
        let option = option?;

        match option["binary"].as_object()?.get("args")?.as_array() {
            Some(options) => {
                return Some(
                    options
                        .iter()
                        .filter_map(Value::as_str)
                        .map(ToString::to_string)
                        .collect::<Vec<_>>(),
                )
            }
            None => {
                log::warn!("args value should be of type [String].");
            }
        };

        None
    }

    pub fn new_buffer(
        &self,
        buffer_id: &BufferId,
        path: &str,
        language_id: &str,
        text: String,
    ) {
        let document_uri = Url::from_file_path(path).unwrap();
        if let Some(client) = self.clients.get(language_id) {
            client.send_did_open(buffer_id, document_uri, language_id, text);
        }
    }

    pub fn save_buffer(&self, buffer: &Buffer) {
        if let Some(client) = self.clients.get(&buffer.language_id) {
            let uri = client.get_uri(buffer);
            client.send_did_save(uri);
        }
    }

    pub fn get_semantic_tokens(&self, buffer: &Buffer) {
        let buffer_id = buffer.id;
        let path = buffer.path.clone();
        let rev = buffer.rev;
        let len = buffer.len();
        if let Some(client) = self.clients.get(&buffer.language_id) {
            let uri = client.get_uri(buffer);
            let local_dispatcher = self.dispatcher.clone().unwrap();