starlark/eval/
params.rs

1/*
2 * Copyright 2018 The Starlark in Rust Authors.
3 * Copyright (c) Facebook, Inc. and its affiliates.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18use crate::eval::ParametersSpec;
19use crate::eval::ParametersSpecParam;
20use crate::typing::ParamSpec;
21use crate::typing::Ty;
22use crate::util::ArcStr;
23
24/// Build both [`ParametersSpec`] (for parsing) and [`ParamSpec`] (for typechecking)
25/// from a list of parameters.
26pub fn param_specs<'a, V: Copy>(
27    function_name: &str,
28    pos_only: impl IntoIterator<Item = (&'a str, ParametersSpecParam<V>, Ty)>,
29    pos_or_named: impl IntoIterator<Item = (&'a str, ParametersSpecParam<V>, Ty)>,
30    args: Option<Ty>,
31    named_only: impl IntoIterator<Item = (&'a str, ParametersSpecParam<V>, Ty)>,
32    kwargs: Option<Ty>,
33) -> crate::Result<(ParametersSpec<V>, ParamSpec)> {
34    let pos_only = Vec::from_iter(pos_only);
35    let pos_or_named = Vec::from_iter(pos_or_named);
36    let named_only = Vec::from_iter(named_only);
37
38    let parameters_spec = ParametersSpec::new_parts(
39        function_name,
40        pos_only.iter().map(|(name, param, _ty)| (*name, *param)),
41        pos_or_named
42            .iter()
43            .map(|(name, param, _ty)| (*name, *param)),
44        args.is_some(),
45        named_only.iter().map(|(name, param, _ty)| (*name, *param)),
46        kwargs.is_some(),
47    );
48
49    let param_spec = ParamSpec::new_parts(
50        pos_only
51            .into_iter()
52            .map(|(_name, param, ty)| (param.is_required(), ty)),
53        pos_or_named
54            .into_iter()
55            .map(|(name, param, ty)| (ArcStr::from(name), param.is_required(), ty)),
56        args,
57        named_only
58            .into_iter()
59            .map(|(name, param, ty)| (ArcStr::from(name), param.is_required(), ty)),
60        kwargs,
61    )?;
62
63    Ok((parameters_spec, param_spec))
64}