| 1914 | } |
| 1915 | |
| 1916 | fn attrs_to_content_items<F, R>( |
| 1917 | attrs: &[Attribute], |
| 1918 | item_new: F, |
| 1919 | ) -> Result<(Vec<R>, Vec<Attribute>)> |
| 1920 | where |
| 1921 | F: Fn(usize, AttrName) -> Result<R>, |
| 1922 | { |
| 1923 | let mut cfgs: Vec<Attribute> = Vec::new(); |
| 1924 | let mut result = Vec::new(); |
| 1925 | |
| 1926 | let mut iter = attrs.iter().enumerate().peekable(); |
| 1927 | while let Some((_, attr)) = iter.peek() { |
| 1928 | // take all cfgs but no py items |
| 1929 | let attr = *attr; |
| 1930 | let attr_name = if let Some(ident) = attr.get_ident() { |
| 1931 | ident.to_string() |
| 1932 | } else { |
| 1933 | continue; |
| 1934 | }; |
| 1935 | if attr_name == "cfg" { |
| 1936 | cfgs.push(attr.clone()); |
| 1937 | } else if ALL_ALLOWED_NAMES.contains(&attr_name.as_str()) { |
| 1938 | break; |
| 1939 | } |
| 1940 | iter.next(); |
| 1941 | } |
| 1942 | |
| 1943 | for (i, attr) in iter { |
| 1944 | // take py items but no cfgs |
| 1945 | let attr_name = if let Some(ident) = attr.get_ident() { |
| 1946 | ident.to_string() |
| 1947 | } else { |
| 1948 | continue; |
| 1949 | }; |
| 1950 | if attr_name == "cfg" { |
| 1951 | bail_span!(attr, "#[py*] items must be placed under `cfgs`",); |
| 1952 | } |
| 1953 | let attr_name = match AttrName::from_str(attr_name.as_str()) { |
| 1954 | Ok(name) => name, |
| 1955 | Err(wrong_name) => { |
| 1956 | if ALL_ALLOWED_NAMES.contains(&attr_name.as_str()) { |
| 1957 | bail_span!(attr, "#[pyclass] doesn't accept #[{}]", wrong_name) |
| 1958 | } else { |
| 1959 | continue; |
| 1960 | } |
| 1961 | } |
| 1962 | }; |
| 1963 | |
| 1964 | result.push(item_new(i, attr_name)?); |
| 1965 | } |
| 1966 | Ok((result, cfgs)) |
| 1967 | } |
| 1968 | |
| 1969 | #[allow(dead_code)] |
| 1970 | fn parse_vec_ident( |