stock-trek 0.5.3

Stock Trek time-series analysis
Documentation
use crate::{
    error::result::StockTrekResult,
    verification::{
        file_existence_verifier::FileExistenceVerifier,
        node_location::NodeLocation,
        path_util::{collate, path_string},
        policy::{BlockedLocations, SyntaxPolicy},
        syntax_verifier::SyntaxVerifier,
        verifier_map::{blocked_node_policy, node_to_location, rust_node, VerifierMap},
    },
};

pub fn verify(path: String) -> StockTrekResult<()> {
    let file_existence_verifier = FileExistenceVerifier::new();
    match file_existence_verifier.verify(path) {
        Err(e) => Err(e),
        Ok(contents) => {
            let mut syntax_verifier = create_syntax_verifier();
            syntax_verifier.verify(&contents)
        }
    }
}

const ALLOWED_ATTRIBUTE_PATH: &str = "register_algorithm";
const ALLOWED_PATH_PREFIXES: &[&str] = &[
    ALLOWED_ATTRIBUTE_PATH,
    "crate::",
    "super::",
    "self::",
    "std::collections::",
    "stock_trek::",
];

fn allowed_by_prefix(path_str: &str) -> bool {
    ALLOWED_PATH_PREFIXES
        .iter()
        .any(|&p| path_str.starts_with(p))
}

fn create_syntax_verifier() -> SyntaxVerifier {
    let mut verifiers = VerifierMap::new();
    verifiers
        .allow::<rust_node::AngleBracketedGenericArguments>()
        .allow::<rust_node::Arm>()
        .allow::<rust_node::AssocConst>()
        .allow::<rust_node::AssocType>()
        .allow::<rust_node::BinOp>()
        .allow::<rust_node::Block>()
        .allow::<rust_node::Constraint>()
        .allow::<rust_node::Expr>()
        .allow::<rust_node::ExprArray>()
        .allow::<rust_node::ExprAssign>()
        .allow::<rust_node::ExprBinary>()
        .allow::<rust_node::ExprBlock>()
        .allow::<rust_node::ExprBreak>()
        .allow::<rust_node::ExprCall>()
        .allow::<rust_node::ExprCast>()
        .allow::<rust_node::ExprClosure>()
        .allow::<rust_node::ExprConst>()
        .allow::<rust_node::ExprContinue>()
        .allow::<rust_node::ExprField>()
        .allow::<rust_node::ExprForLoop>()
        .allow::<rust_node::ExprGroup>()
        .allow::<rust_node::ExprIf>()
        .allow::<rust_node::ExprIndex>()
        .allow::<rust_node::ExprInfer>()
        .allow::<rust_node::ExprLet>()
        .allow::<rust_node::ExprLit>()
        .allow::<rust_node::ExprLoop>()
        .allow::<rust_node::ExprMatch>()
        .allow::<rust_node::ExprMethodCall>()
        .allow::<rust_node::ExprParen>()
        .allow::<rust_node::ExprRange>()
        .allow::<rust_node::ExprReference>()
        .allow::<rust_node::ExprRepeat>()
        .allow::<rust_node::ExprReturn>()
        .allow::<rust_node::ExprStruct>()
        .allow::<rust_node::ExprTuple>()
        .allow::<rust_node::ExprUnary>()
        .allow::<rust_node::ExprWhile>()
        .allow::<rust_node::Field>()
        .allow::<rust_node::FieldPat>()
        .allow::<rust_node::FieldValue>()
        .allow::<rust_node::Fields>()
        .allow::<rust_node::FieldsNamed>()
        .allow::<rust_node::FieldsUnnamed>()
        .allow::<rust_node::File>()
        .allow::<rust_node::FnArg>()
        .allow::<rust_node::GenericArgument>()
        .allow::<rust_node::GenericParam>()
        .allow::<rust_node::Generics>()
        .allow::<rust_node::Ident>()
        .allow::<rust_node::ImplItem>()
        .allow::<rust_node::ImplItemConst>()
        .allow::<rust_node::ImplItemFn>()
        .allow::<rust_node::ImplItemType>()
        .allow::<rust_node::Index>()
        .allow::<rust_node::Item>()
        .allow::<rust_node::ItemConst>()
        .allow::<rust_node::ItemEnum>()
        .allow::<rust_node::ItemFn>()
        .allow::<rust_node::ItemImpl>()
        .allow::<rust_node::ItemStruct>()
        .allow::<rust_node::ItemTrait>()
        .allow::<rust_node::ItemTraitAlias>()
        .allow::<rust_node::ItemType>()
        .allow::<rust_node::ItemUnion>()
        .allow::<rust_node::Label>()
        .allow::<rust_node::Lifetime>()
        .allow::<rust_node::LifetimeParam>()
        .allow::<rust_node::Lit>()
        .allow::<rust_node::LitBool>()
        .allow::<rust_node::LitByte>()
        .allow::<rust_node::LitByteStr>()
        .allow::<rust_node::LitCStr>()
        .allow::<rust_node::LitChar>()
        .allow::<rust_node::LitFloat>()
        .allow::<rust_node::LitInt>()
        .allow::<rust_node::LitStr>()
        .allow::<rust_node::Local>()
        .allow::<rust_node::Member>()
        .allow::<rust_node::Meta>()
        .allow::<rust_node::MetaList>()
        .allow::<rust_node::MetaNameValue>()
        .allow::<rust_node::ParenthesizedGenericArguments>()
        .allow::<rust_node::Pat>()
        .allow::<rust_node::PatIdent>()
        .allow::<rust_node::PatOr>()
        .allow::<rust_node::PatParen>()
        .allow::<rust_node::PatReference>()
        .allow::<rust_node::PatRest>()
        .allow::<rust_node::PatSlice>()
        .allow::<rust_node::PatStruct>()
        .allow::<rust_node::PatTuple>()
        .allow::<rust_node::PatTupleStruct>()
        .allow::<rust_node::PatType>()
        .allow::<rust_node::PatWild>()
        .allow::<rust_node::PathArguments>()
        .allow::<rust_node::PathSegment>()
        .allow::<rust_node::PredicateLifetime>()
        .allow::<rust_node::PredicateType>()
        .allow::<rust_node::QSelf>()
        .allow::<rust_node::RangeLimits>()
        .allow::<rust_node::Receiver>()
        .allow::<rust_node::ReturnType>()
        .allow::<rust_node::Signature>()
        .allow::<rust_node::Stmt>()
        .allow::<rust_node::TraitBound>()
        .allow::<rust_node::TraitBoundModifier>()
        .allow::<rust_node::TraitItem>()
        .allow::<rust_node::TraitItemConst>()
        .allow::<rust_node::TraitItemFn>()
        .allow::<rust_node::TraitItemType>()
        .allow::<rust_node::Type>()
        .allow::<rust_node::TypeArray>()
        .allow::<rust_node::TypeGroup>()
        .allow::<rust_node::TypeImplTrait>()
        .allow::<rust_node::TypeInfer>()
        .allow::<rust_node::TypeNever>()
        .allow::<rust_node::TypeParam>()
        .allow::<rust_node::TypeParamBound>()
        .allow::<rust_node::TypeParen>()
        .allow::<rust_node::TypePath>()
        .allow::<rust_node::TypeReference>()
        .allow::<rust_node::TypeSlice>()
        .allow::<rust_node::TypeTraitObject>()
        .allow::<rust_node::TypeTuple>()
        .allow::<rust_node::UnOp>()
        .allow::<rust_node::UseGroup>()
        .allow::<rust_node::UseName>()
        .allow::<rust_node::UsePath>()
        .allow::<rust_node::UseTree>()
        .allow::<rust_node::Variant>()
        .allow::<rust_node::VisRestricted>()
        .allow::<rust_node::Visibility>()
        .allow::<rust_node::WhereClause>()
        .allow::<rust_node::WherePredicate>();
    //

    fn verify_node_path<N: syn::spanned::Spanned>(node: &N, path: &str) -> SyntaxPolicy {
        if allowed_by_prefix(path) || !path.contains("::") {
            SyntaxPolicy::Allowed
        } else {
            blocked_node_policy(node)
        }
    }

    verifiers
        .scope::<rust_node::Attribute>(|node| {
            let is_allowed = match &node.meta {
                syn::Meta::Path(path) => ALLOWED_ATTRIBUTE_PATH == path_string(path),
                _ => false,
            };
            if is_allowed {
                SyntaxPolicy::Allowed
            } else {
                blocked_node_policy(node)
            }
        })
        .scope::<rust_node::ExprPath>(|node| {
            let expr_path_str = &path_string(&node.path);
            verify_node_path(node, expr_path_str)
        })
        .scope::<rust_node::Path>(|node| {
            let path_str = &path_string(node);
            verify_node_path(node, path_str)
        })
        .scope::<rust_node::ItemUse>(|node| {
            let locations: Vec<NodeLocation> = collate(&node.tree)
                .iter()
                .filter(|path| !allowed_by_prefix(path))
                .map(|_| node_to_location(node))
                .collect();
            if locations.is_empty() {
                SyntaxPolicy::Allowed
            } else {
                SyntaxPolicy::Blocked(BlockedLocations { locations })
            }
        });
    //
    verifiers
        .block::<rust_node::Abi>()
        .block::<rust_node::BareFnArg>()
        .block::<rust_node::BareVariadic>()
        .block::<rust_node::BoundLifetimes>()
        .block::<rust_node::CapturedParam>()
        .block::<rust_node::ConstParam>()
        .block::<rust_node::DeriveInput>()
        .block::<rust_node::ExprAsync>()
        .block::<rust_node::ExprAwait>()
        .block::<rust_node::ExprMacro>()
        .block::<rust_node::ExprRawAddr>()
        .block::<rust_node::ExprTry>()
        .block::<rust_node::ExprTryBlock>()
        .block::<rust_node::ExprUnsafe>()
        .block::<rust_node::ExprYield>()
        .block::<rust_node::ForeignItem>()
        .block::<rust_node::ForeignItemFn>()
        .block::<rust_node::ForeignItemMacro>()
        .block::<rust_node::ForeignItemStatic>()
        .block::<rust_node::ForeignItemType>()
        .block::<rust_node::ImplItemMacro>()
        .block::<rust_node::ItemExternCrate>()
        .block::<rust_node::ItemForeignMod>()
        .block::<rust_node::ItemMacro>()
        .block::<rust_node::ItemMod>()
        .block::<rust_node::ItemStatic>()
        .block::<rust_node::Macro>()
        .block::<rust_node::PointerMutability>()
        .block::<rust_node::PreciseCapture>()
        .block::<rust_node::StaticMutability>()
        .block::<rust_node::StmtMacro>()
        .block::<rust_node::TraitItemMacro>()
        .block::<rust_node::TypeBareFn>()
        .block::<rust_node::TypeMacro>()
        .block::<rust_node::TypePtr>()
        .block::<rust_node::UseGlob>()
        .block::<rust_node::UseRename>()
        .block::<rust_node::Variadic>();

    SyntaxVerifier::new(verifiers)
}