1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use crate::clib;
use crate::question::{alpm_question_t, QuestionArgs};
use std::os::raw::c_char;

use super::{alpm_handle_t, Handle};

#[link(name = "alpm")]
extern "C" {
    fn alpm_option_set_logcb(
        handle: *mut alpm_handle_t,
        f: extern "C" fn(i32, *mut c_char, clib::VaList),
    ) -> i32;
    fn alpm_option_set_dlcb(
        handle: *mut alpm_handle_t,
        f: extern "C" fn(filename: *mut c_char, xfered: i64, total: i64),
    ) -> i32;
    fn alpm_option_set_questioncb(
        handle: *mut alpm_handle_t,
        f: extern "C" fn(question: *mut alpm_question_t),
    ) -> i32;
}

/*
type LogCallback = Option<Fn(i32,String)>;
type DownloadCallback<T: Fn(&str,i64,i64)> = T;
type QuestionCallback<T: Fn(QuestionArgs)> = T;


static mut LOG_CALLBACK : Option<Box<LogCallback>> = None;
static mut DOWNLOAD_CALLBACK : Option<DownloadCallback> = None;
static mut QUESTION_CALLBACK : Option<QuestionCallback> = None;
*/

type LogCallback = Fn(i32, String);
type DownloadCallback = Fn(&str, i64, i64);
type QuestionCallback = Fn(QuestionArgs);

static mut LOG_CALLBACK: Option<Box<LogCallback>> = None;
static mut DOWNLOAD_CALLBACK: Option<Box<DownloadCallback>> = None;
static mut QUESTION_CALLBACK: Option<Box<QuestionCallback>> = None;

extern "C" fn alpm_log_cb_handler(level: i32, fmt: *mut c_char, args: clib::VaList) {
    unsafe {
        if let Some(f) = &LOG_CALLBACK {
            let out = clib::vsn_printf(fmt, args);
            f(level, out);
        }
    }
}

pub fn set_log_callback<T: Fn(i32, String) + 'static>(h: &Handle, cb: T) {
    unsafe {
        match LOG_CALLBACK {
            None => {
                alpm_option_set_logcb(h.alpm_handle, alpm_log_cb_handler);
            }
            _ => {}
        }
        LOG_CALLBACK = Some(Box::new(cb));
    }
}

extern "C" fn alpm_log_download_handler(filename: *mut c_char, xfered: i64, total: i64) {
    unsafe {
        if let Some(f) = &DOWNLOAD_CALLBACK {
            f(cstr!(filename), xfered, total);
        }
    }
}

pub fn set_download_callback<T: Fn(&str, i64, i64) + 'static>(h: &Handle, cb: T) {
    unsafe {
        match DOWNLOAD_CALLBACK {
            None => {
                alpm_option_set_dlcb(h.alpm_handle, alpm_log_download_handler);
            }
            _ => {}
        }
        DOWNLOAD_CALLBACK = Some(Box::new(cb));
    }
}

extern "C" fn alpm_question_handler(q_raw: *mut alpm_question_t) {
    unsafe {
        if let Some(f) = &QUESTION_CALLBACK {
            f(q_raw.into());
        }
    }
}

pub fn set_question_callback<T: Fn(QuestionArgs) + 'static>(h: &Handle, cb: T) {
    unsafe {
        match QUESTION_CALLBACK {
            None => {
                alpm_option_set_questioncb(h.alpm_handle, alpm_question_handler);
            }
            _ => {}
        }
        QUESTION_CALLBACK = Some(Box::new(cb));
    }
}