backup_lib 0.2.0

backup macro to inject function into mod and actor
Documentation
#[macro_export]
macro_rules! inject_backup_api {
    () => {
        use backup_lib::backup_info::*;

        // call backup controller to get job list
        #[update(name = "backup_job_list", guard = "owner_guard")]
        #[candid_method(update, rename = "backup_job_list")]
        pub fn backup_job_list() -> Result<Vec<BackupJob>, String> {
            let jobs = job_list();
            Ok(jobs)
        }

        #[update(name = "start_backup", guard = "owner_guard")]
        #[candid_method(update, rename = "start_backup")]
        pub fn start_backup() {
            backup_job_start();
        }

        #[update(name = "finish_backup", guard = "owner_guard")]
        #[candid_method(update, rename = "finish_backup")]
        pub fn finish_backup() {
            backup_job_finish();
        }

        ///
        /// following is the import/export process
        ///
        // called by backup runner, to read data from canister
        #[update(name = "job_data_export", guard = "owner_guard")]
        #[candid_method(update, rename = "job_data_export")]
        pub fn job_data_export(name: String, start: usize, end: usize) -> Result<Option<ByteReadResponse>, String> {
            info_log_add(format!("job_data_export name:{}, start:{}, end:{}", name, start, end).as_str());

            let resp: Option<ByteReadResponse> = record_export(name.clone(), start, end);
            Ok(resp)
        }

        // called by backup runner, to write data to canister
        #[update(name = "job_data_import", guard = "owner_guard")]
        #[candid_method(update, rename = "job_data_import")]
        pub fn job_data_import(req: ByteWriteRequest) -> Result<bool, String> {
            info_log_add(format!("job_data_import name:{}, hash:{}", req.name, req.hash).as_str());
            let ret: bool = record_import(req.clone());
            Ok(ret)
        }

        // call by backup controller, prepare for export start
        #[update(name = "job_export_init", guard = "owner_guard")]
        #[candid_method(update, rename = "job_export_init")]
        pub fn job_export_init() -> Result<(), String> {
            info_log_add("job_export_init");

            match export_init_cb() {
                Ok(_) => {
                    let backup_controller_id = caller();
                    info_log_add(format!("call on_job_export_init on target_canister_id: {}", backup_controller_id).as_str());
                    let _result = ic_cdk::api::call::notify(backup_controller_id, "on_job_export_init", ());
                    Ok(())
                },
                Err(msg) => {
                    Err(msg)
                }
            }
        }

        // call by backup controller, notify export finished
        #[update(name = "job_export_finish", guard = "owner_guard")]
        #[candid_method(update, rename = "job_export_finish")]
        pub fn job_export_finish() -> Result<(), String> {
            info_log_add("job_export_finish");
            export_finish_cb();

            Ok(())
        }

        // call backup controller to start import job
        #[update(name = "job_import_init", guard = "owner_guard")]
        #[candid_method(update, rename = "job_import_init")]
        pub fn job_import_init(jobs: Vec<BackupJob>) -> Result<(), String> {
            info_log_add("job_import_init");
            match import_init_cb(jobs){
                Ok(_) => {
                    let backup_controller_id = caller();
                    info_log_add(format!("call on_job_import_init on target_canister_id: {}", backup_controller_id).as_str());
                    let _result = ic_cdk::api::call::notify(backup_controller_id, "on_job_import_init", ());
                    Ok(())
                },
                Err(msg) => {
                    Err(msg)
                }
            }
        }

        // call by backup controller, notify restore finished
        #[update(name = "job_import_finish", guard = "owner_guard")]
        #[candid_method(update, rename = "job_import_finish")]
        pub fn job_import_finish() -> Result<(), String> {
            info_log_add("job_import_finish");
            import_finish_cb();

            Ok(())
        }

        ///
        /// following is the backup/restore process
        /// use stable memory to read/write record
        ///
        // called by backup runner, to write data to stable memory
        #[update(name = "job_data_write", guard = "owner_guard")]
        #[candid_method(update, rename = "job_data_write")]
        pub fn job_data_write(name: String, start: usize, end: usize) -> Result<bool, String> {
            info_log_add(format!("job_data_write name:{}, start:{}, end:{}", name, start, end).as_str());

            let ret:bool = record_write(name.clone(), start, end);
            Ok(ret)
        }

        // called by backup runner, to read data from stable memory
        #[update(name = "job_data_read", guard = "owner_guard")]
        #[candid_method(update, rename = "job_data_read")]
        pub fn job_data_read(name: String, start: usize, end: usize) -> Result<bool, String> {
            info_log_add(format!("job_data_read name:{}, start:{}, end:{}", name, start, end).as_str());
            let ret:bool = record_read(name.clone(), start, end);
            Ok(ret)
        }

        // call by backup controller, prepare for backup start
        #[update(name = "job_backup_init", guard = "owner_guard")]
        #[candid_method(update, rename = "job_backup_init")]
        pub fn job_backup_init() -> Result<(), String> {
            info_log_add("job_backup_init");

            match backup_init_cb(){
                Ok(_) => {
                    let backup_controller_id = caller();
                    info_log_add(format!("call on_job_backup_init on target_canister_id: {}", backup_controller_id).as_str());
                    let _result = ic_cdk::api::call::notify(backup_controller_id, "on_job_backup_init", ());

                    Ok(())
                },
                Err(msg) => {
                    Err(msg)
                }
            }
        }

        // call by backup controller, notify backup finished
        #[update(name = "job_backup_finish", guard = "owner_guard")]
        #[candid_method(update, rename = "job_backup_finish")]
        pub fn job_backup_finish() -> Result<(), String> {
            info_log_add("job_backup_finish");
            backup_finish_cb();

            Ok(())
        }

        // call backup controller to start restore job
        #[update(name = "job_restore_init", guard = "owner_guard")]
        #[candid_method(update, rename = "job_restore_init")]
        pub fn job_restore_init(jobs: Vec<BackupJob>) -> Result<(), String> {
            info_log_add("job_restore_init");

            match restore_init_cb(jobs) {
                Ok(_) => {
                    let backup_controller_id = caller();
                    info_log_add(format!("call on_job_restore_init on target_canister_id: {}", backup_controller_id).as_str());
                    let _result = ic_cdk::api::call::notify(backup_controller_id, "on_job_restore_init", ());
                    Ok(())
                },
                Err(msg) => {
                    Err(msg)
                }
            }
        }

        // call by backup controller, notify restore finished
        #[update(name = "job_restore_finish", guard = "owner_guard")]
        #[candid_method(update, rename = "job_restore_finish")]
        pub fn job_restore_finish() -> Result<(), String> {
            info_log_add("job_restore_finish");
            restore_finish_cb();

            Ok(())
        }
    }
}