Skip to content

Granular wrapping of the R api #240

@CGMossa

Description

@CGMossa

It has been a long-term goal of mine, to include the totality of the R C-API in libR-sys.
Right now, libR-sys only serves as a sys-crate for extendr, and it primarily follows the needs of extendr.

But it would be nice if libR-sys could be used for all R-API needs in Rust.

To that end, I've made a prototype of how such a project can look like, see
https://github.com/CGMossa/modern_libr
(see discord discussion for reference)
https://discord.com/channels/751419551132155925/751419551132155928/1136068899507540078

Essentially, the resulting lib.rs will roughly look like this

Details

#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(ambiguous_glob_reexports)]

pub mod bindings {
    #[path = "R.rs"]
    pub mod r;

    #[path = "Rinternals.rs"]
    pub mod r_internals {
        use super::r_ext::boolean::Rboolean;
        use super::r_ext::complex::Rcomplex;
        use super::r_ext::r_dynload::DL_FUNC;

        include!("bindings/Rinternals.rs");
    }

    #[path = "Rmath.rs"]
    pub mod r_math;

    #[path = "Rversion.rs"]
    pub mod r_version;

    //TODO: unix specific?
    // #[path = "Rinterface.rs"]
    // pub mod r_interface;
    // pub use r_interface::*;

    pub mod r_embedded {
        use super::r_ext::boolean::Rboolean;

        include!("bindings/Rembedded.rs");
    }

    #[path = "R_ext"]
    pub mod r_ext {
        pub mod applic {
            use super::boolean::Rboolean;
            include!("bindings/R_ext/Applic.rs");
        }

        pub mod blas {
            use super::complex::Rcomplex;
            include!("bindings/R_ext/BLAS.rs");
        }

        // #[path = "Callbacks.rs"]
        pub mod callbacks {
            use super::super::r_internals::SEXP;
            use super::boolean::Rboolean;

            include!("bindings/R_ext/Callbacks.rs");
        }

        //TODO: another platform?
        // #[path = "GetX11Image.rs"]
        // pub mod GetX11Image;

        // #[path ="Lapack.rs"]
        pub mod lapack {
            use super::complex::Rcomplex;
            include!("bindings/R_ext/Lapack.rs");
        }

        #[path = "Linpack.rs"]
        pub mod linpack;

        #[path = "Parse.rs"]
        pub mod parse {
            use super::super::r_internals::SEXP;
            include!("bindings/R_ext/Parse.rs");
        }

        pub mod r_startup {
            use super::boolean::Rboolean;
            include!("bindings/R_ext/RStartup.rs");
        }

        pub mod r_dynload {
            use super::boolean::Rboolean;
            include!("bindings/R_ext/Rdynload.rs");
        }

        #[path = "Riconv.rs"]
        pub mod r_iconv;

        #[path = "Visibility.rs"]
        pub mod visibility;

        // TODO: another platform?
        // #[path ="eventloop.rs"]
        // pub mod event_loop;

        #[path = "Boolean.rs"]
        pub mod boolean;

        #[path = "Complex.rs"]
        pub mod complex;

        #[path = "Arith.rs"]
        pub mod arith;

        #[path = "Constants.rs"]
        pub mod constants;

        #[path = "Error.rs"]
        pub mod error;

        #[path = "Memory.rs"]
        pub mod memory;

        #[path = "Print.rs"]
        pub mod print;

        #[path = "RS.rs"]
        pub mod rs;

        #[path = "Random.rs"]
        pub mod random;

        #[path = "Utils.rs"]
        pub mod utils {
            use super::complex::Rcomplex;
            use super::boolean::Rboolean;

            include!("bindings/R_ext/Utils.rs");
        }

        //TODO: this is windows specific.
        #[path = "libextern.rs"]
        pub mod libextern;
    }

    #[path = "Rconfig.rs"]
    pub mod r_config;

    pub mod r_prelude {
        pub use super::r_config::*;
        pub use super::r_ext::arith::*;
        pub use super::r_ext::boolean::*;
        pub use super::r_ext::complex::*;
        pub use super::r_ext::constants::*;
        pub use super::r_ext::error::*;
        pub use super::r_ext::libextern::*;
        pub use super::r_ext::memory::*;
        pub use super::r_ext::print::*;
        pub use super::r_ext::random::*;
        pub use super::r_ext::rs::*;
        pub use super::r_ext::utils::*;
    }
}

There are challenges that need to be dealt with before this can be a reality:

  • Faster processing of bindings, as right now, in modern_libr uses clang to filter out elements. Luckily, we are about to land Remove clang-sys dependency #238 that serves as a schematic for how to accomplish this.
  • Paths to module-files has to be target, R version and platform dependent. This means that the module notation of #[path = <path>] has to depend on these things, for the seamless experience, that is.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions