Repository: paritytech/substrate
File: primitives/api/proc-macro/src/impl_runtime_apis.rs (Rust)

Code before:
			} else if m.path.is_ident(API_VERSION_ATTRIBUTE) {
				let content;
				parenthesized!(content in m.input);
				let ver: LitInt = content.parse()?;
				api_version = Some(ver.base10_parse::<u64>()?);
			}
			Ok(())
		})?;

		// If there is a cfg attribute containing api_version - save if for processing
		if let (Some(feature_name), Some(api_version)) = (feature_name, api_version) {
			cfg_api_version_attr.push((feature_name, api_version, cfg_attr.span()));
		}
	}

	if cfg_api_version_attr.len() > 1 {
		let mut err = Error::new(span, format!("Found multiple feature gated api versions (cfg attribute with nested `{}` attribute). This is not supported.", API_VERSION_ATTRIBUTE));
		for (_, _, attr_span) in cfg_api_version_attr {
			err.combine(Error::new(attr_span, format!("`{}` found here", API_VERSION_ATTRIBUTE)));
		}

		return Err(err)
	}

	let result = cfg_api_version_attr.drain(..).next().map(|(feature, name, _)| (feature, name));
	Ok(result)
}

/// Represents an API version.
struct ApiVersion {
	/// Corresponds to `#[api_version(X)]` attribute.
	pub custom: Option<u64>,
	/// Corresponds to `#[cfg_attr(feature = "enable-staging-api", api_version(99))]`
	/// attribute. `String` is the feature name, `u64` the staging api version.
	pub feature_gated: Option<(String, u64)>,
}

// Extracts the value of `API_VERSION_ATTRIBUTE` and handles errors.
// Returns:
// - Err if the version is malformed
// - `ApiVersion` on success. If a version is set or not is determined by the fields of `ApiVersion`
fn extract_api_version(attrs: &Vec<Attribute>, span: Span) -> Result<ApiVersion> {
	// First fetch all `API_VERSION_ATTRIBUTE` values (should be only one)
	let api_ver = attrs
		.iter()
		.filter(|a| a.path().is_ident(API_VERSION_ATTRIBUTE))
		.collect::<Vec<_>>();

	if api_ver.len() > 1 {
		return Err(Error::new(
			span,

Review comment (suggestion):
```suggestion
	Ok(cfg_api_version_attr.drain(..).next().map(|(feature, name, _)| (feature, name)))
```

Code after:

		// If there is a cfg attribute containing api_version - save if for processing
		if let (Some(feature_name), Some(api_version)) = (feature_name, api_version) {
			cfg_api_version_attr.push((feature_name, api_version, cfg_attr.span()));
		}
	}

	if cfg_api_version_attr.len() > 1 {
		let mut err = Error::new(span, format!("Found multiple feature gated api versions (cfg attribute with nested `{}` attribute). This is not supported.", API_VERSION_ATTRIBUTE));
		for (_, _, attr_span) in cfg_api_version_attr {
			err.combine(Error::new(attr_span, format!("`{}` found here", API_VERSION_ATTRIBUTE)));
		}

		return Err(err)
	}

	Ok(cfg_api_version_attr
		.into_iter()
		.next()
		.map(|(feature, name, _)| (feature, name)))
}

/// Represents an API version.
struct ApiVersion {
	/// Corresponds to `#[api_version(X)]` attribute.
	pub custom: Option<u64>,
	/// Corresponds to `#[cfg_attr(feature = "enable-staging-api", api_version(99))]`
	/// attribute. `String` is the feature name, `u64` the staging api version.
	pub feature_gated: Option<(String, u64)>,
}

// Extracts the value of `API_VERSION_ATTRIBUTE` and handles errors.
// Returns:
// - Err if the version is malformed
// - `ApiVersion` on success. If a version is set or not is determined by the fields of `ApiVersion`
fn extract_api_version(attrs: &Vec<Attribute>, span: Span) -> Result<ApiVersion> {
	// First fetch all `API_VERSION_ATTRIBUTE` values (should be only one)
	let api_ver = attrs
		.iter()
		.filter(|a| a.path().is_ident(API_VERSION_ATTRIBUTE))
		.collect::<Vec<_>>();

	if api_ver.len() > 1 {
		return Err(Error::new(
			span,
			format!(
				"Found multiple #[{}] attributes for an API implementation. \
				Each runtime API can have only one version.",
				API_VERSION_ATTRIBUTE
			),
		))