mirror of
https://github.com/github/codeql.git
synced 2026-04-08 00:24:03 +02:00
Rust: fix reading lists from options.yml
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
mod deserialize_vec;
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
use codeql_extractor::trap;
|
||||
use deserialize_vec::deserialize_newline_or_comma_separated;
|
||||
use figment::{
|
||||
providers::{Env, Format, Serialized, Yaml},
|
||||
value::Value,
|
||||
@@ -14,7 +17,7 @@ use ra_ap_intern::Symbol;
|
||||
use ra_ap_paths::Utf8PathBuf;
|
||||
use ra_ap_project_model::{CargoConfig, CargoFeatures, CfgOverrides, RustLibSource};
|
||||
use rust_extractor_macros::extractor_cli_config;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Not;
|
||||
use std::path::PathBuf;
|
||||
@@ -37,14 +40,6 @@ impl From<Compression> for trap::Compression {
|
||||
}
|
||||
}
|
||||
|
||||
// required by the extractor_cli_config macro.
|
||||
fn deserialize_newline_or_comma_separated<'a, D: Deserializer<'a>, T: for<'b> From<&'b str>>(
|
||||
deserializer: D,
|
||||
) -> Result<Vec<T>, D::Error> {
|
||||
let value = String::deserialize(deserializer)?;
|
||||
Ok(value.split(['\n', ',']).map(T::from).collect())
|
||||
}
|
||||
|
||||
#[extractor_cli_config]
|
||||
pub struct Config {
|
||||
pub scratch_dir: PathBuf,
|
||||
|
||||
49
rust/extractor/src/config/deserialize_vec.rs
Normal file
49
rust/extractor/src/config/deserialize_vec.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use serde::de::Visitor;
|
||||
use serde::Deserializer;
|
||||
use std::fmt::Formatter;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
// phantom data ise required to allow parametrizing on `T` without actual `T` data
|
||||
struct VectorVisitor<T: From<String>>(PhantomData<T>);
|
||||
|
||||
impl<T: From<String>> VectorVisitor<T> {
|
||||
fn new() -> Self {
|
||||
VectorVisitor(PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T: From<String>> Visitor<'de> for VectorVisitor<T> {
|
||||
type Value = Vec<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("either a sequence, or a comma or newline separated string")
|
||||
}
|
||||
|
||||
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Vec<T>, E> {
|
||||
Ok(value
|
||||
.split(['\n', ','])
|
||||
.map(|s| T::from(s.to_owned()))
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
|
||||
where
|
||||
A: serde::de::SeqAccess<'de>,
|
||||
{
|
||||
let mut ret = Vec::new();
|
||||
while let Some(el) = seq.next_element::<String>()? {
|
||||
ret.push(T::from(el));
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
/// deserialize into a vector of `T` either of:
|
||||
/// * a sequence of elements serializable into `String`s, or
|
||||
/// * a single element serializable into `String`, then split on `,` and `\n`
|
||||
/// This is required to be in scope when the `extractor_cli_config` macro is used.
|
||||
pub(crate) fn deserialize_newline_or_comma_separated<'a, D: Deserializer<'a>, T: From<String>>(
|
||||
deserializer: D,
|
||||
) -> Result<Vec<T>, D::Error> {
|
||||
deserializer.deserialize_seq(VectorVisitor::new())
|
||||
}
|
||||
Reference in New Issue
Block a user