pub fn scan_args<Req, Opt, Splat, Trail, Kw, Block>(
args: &[Value]
) -> Result<Args<Req, Opt, Splat, Trail, Kw, Block>, Error>where
Req: ScanArgsRequired,
Opt: ScanArgsOpt,
Splat: ScanArgsSplat,
Trail: ScanArgsRequired,
Kw: ScanArgsKw,
Block: ScanArgsBlock,
Expand description
Retrieves arguments from a slice.
This function can be used to implement Ruby methods with more complex signatures, including optional arguments and ‘splats’.
The format of the arguments required is driven by the types in the return
value. The stuct Args
is returned but the types of its fields are
determined by type parameters. The type ()
is used as a placeholder when
a set of arguments is not required.
Examples
TCPServer::new
’s argument handling. This is roughly equivalent to
def new(hostname=nil, port)
.
use magnus::{define_class, error::Error, function, scan_args::scan_args, Object, Value};
fn tcp_svr_init(args: &[Value]) -> Result<Value, Error> {
let args = scan_args(args)?;
let _: () = args.required;
let (hostname,): (Option<String>,) = args.optional;
let _: () = args.splat;
let (port,): (u16,) = args.trailing;
let _: () = args.keywords;
let _: () = args.block;
// ...
}
let class = define_class("TCPServer", Default::default()).unwrap();
class.define_singleton_method("new", function!(tcp_svr_init, -1)).unwrap();
The same example as above, specifying the types slightly differently.
use magnus::{define_class, error::Error, function, scan_args::scan_args, Object, Value};
fn tcp_svr_init(args: &[Value]) -> Result<Value, Error> {
let args = scan_args::<(), (Option<String>,), (), (u16,), (), ()>(args)?;
let (hostname,) = args.optional;
let (port,) = args.trailing;
// ...
}
let class = define_class("TCPServer", Default::default()).unwrap();
class.define_singleton_method("new", function!(tcp_svr_init, -1)).unwrap();
Addrinfo::getaddrinfo
’s argument handling. This is roughly equivalent to
def getaddrinfo(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil)
.
use magnus::{
define_class, error::Error, function, scan_args::{scan_args, get_kwargs}, Object, RHash, Symbol, Value,
};
fn getaddrinfo(args: &[Value]) -> Result<Value, Error> {
let args = scan_args::<_, _, (), (), _, ()>(args)?;
let (nodename, service): (String, u16) = args.required;
let (family, socktype, protocol, flags): (
Option<Symbol>,
Option<Symbol>,
Option<i64>,
Option<i64>,
) = args.optional;
let kw = get_kwargs::<_, (), (Option<usize>,), ()>(args.keywords, &[], &["timeout"])?;
let (timeout,) = kw.optional;
// ...
}
let class = define_class("Addrinfo", Default::default()).unwrap();
class.define_singleton_method("getaddrinfo", function!(getaddrinfo, -1)).unwrap();