<commit_before>use analysis;
use analysis::rust_type::rust_type;
use analysis::type_kind::TypeKind;
use env::Env;
use library;
use traits::*;

pub trait TranslateFromGlib {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String);
}

//TODO: move to code for analysis::return_value::Info
impl TranslateFromGlib for library::Parameter {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        let kind = TypeKind::of(&env.library, self.typ);
        match kind {
            TypeKind::Converted => ("from_glib(".into(), ")".into()),
            TypeKind::Direct |
                TypeKind::Enumeration => (String::new(), String::new()),
            //TODO: check gtk_dialog_get_content_area <type name="Box" c:type="GtkWidget*"/>
            TypeKind::Pointer | //Checked only for Option<String>
                TypeKind::Object => from_glib_xxx(self.transfer),
            _ => (format!("TODO {:?}:", kind), String::new()),
        }
    }
}

impl TranslateFromGlib for analysis::return_value::Info {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        match self.parameter {
            Some(ref par) => match self.base_tid {
                Some(tid) => {
                    let rust_type = rust_type(env, tid);
                    let from_glib_xxx = from_glib_xxx(par.transfer);
                    (
                        format!("{}::{}", rust_type.as_str(), from_glib_xxx.0),
                        format!("{}.downcast_unchecked()",from_glib_xxx.1)
                    )
                }
                None => par.translate_from_glib_as_function(env)
            },
            None => (String::new(), ";".into())
        }
    }
}

fn from_glib_xxx(transfer: library::Transfer) -> (String, String) {
    use library::Transfer::*;
    match transfer {
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("TODO:".into(), String::new()),
    }
}
<commit_msg>Fix downcast function for optional returns<commit_after>use analysis;
use analysis::rust_type::rust_type;
use analysis::type_kind::TypeKind;
use env::Env;
use library;
use traits::*;

pub trait TranslateFromGlib {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String);
}

//TODO: move to code for analysis::return_value::Info
impl TranslateFromGlib for library::Parameter {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        let kind = TypeKind::of(&env.library, self.typ);
        match kind {
            TypeKind::Converted => ("from_glib(".into(), ")".into()),
            TypeKind::Direct |
                TypeKind::Enumeration => (String::new(), String::new()),
            TypeKind::Pointer | //Checked only for Option<String>
                TypeKind::Object => from_glib_xxx(self.transfer),
            _ => (format!("TODO {:?}:", kind), String::new()),
        }
    }
}

impl TranslateFromGlib for analysis::return_value::Info {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        match self.parameter {
            Some(ref par) => match self.base_tid {
                Some(tid) => {
                    let rust_type = rust_type(env, tid);
                    let from_glib_xxx = from_glib_xxx(par.transfer);
                    let prefix = if par.nullable {
                        format!("Option::<{}>::{}", rust_type.as_str(), from_glib_xxx.0)
                    } else {
                        format!("{}::{}", rust_type.as_str(), from_glib_xxx.0)
                    };
                    let suffix_function = if par.nullable {
                        "map(Downcast::downcast_unchecked)"
                    } else {
                        "downcast_unchecked()"
                    };
                    (
                        prefix,
                        format!("{}.{}", from_glib_xxx.1, suffix_function)
                    )
                }
                None => par.translate_from_glib_as_function(env)
            },
            None => (String::new(), ";".into())
        }
    }
}

fn from_glib_xxx(transfer: library::Transfer) -> (String, String) {
    use library::Transfer::*;
    match transfer {
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("TODO:".into(), String::new()),
    }
}

{'fraction_non_alphanumeric': 0.1557450628366248, 'fraction_numerical': 0.0011220825852782765, 'mean_word_length': 2.12333566923616, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5506493', 'n_tokens_mistral': 1315, 'n_tokens_neox': 1289, 'n_words': 251}