surrealdb-server 3.1.3

A scalable, distributed, collaborative, document-graph database, for the realtime web
Documentation
use anyhow::Result;
use clap::Args;
use glob::glob;
use surrealdb_core::syn;

#[derive(Args, Debug)]
pub struct ValidateCommandArguments {
	#[arg(help = "Glob pattern for the files to validate")]
	#[arg(default_value = "**/*.surql")]
	patterns: Vec<String>,
	#[arg(long, help = "Read query from standard input")]
	#[arg(conflicts_with = "patterns")]
	stdin: bool,
}

pub async fn init(args: ValidateCommandArguments) -> Result<()> {
	let ValidateCommandArguments {
		patterns,
		stdin,
	} = args;

	if stdin {
		use tokio::io::AsyncReadExt;
		let mut input = String::new();

		if let Err(error) = tokio::io::stdin().read_to_string(&mut input).await {
			return Err(anyhow::anyhow!("Failed to read from stdin: {error}"));
		}

		match syn::parse(&input) {
			Ok(_) => println!("<stdin>: OK"),
			Err(error) => {
				println!("<stdin>: FAIL");
				println!("{error}");
				return Err(anyhow::anyhow!("The query failed to validate"));
			}
		}

		return Ok(());
	}

	let mut entries = vec![];

	for pattern in patterns {
		let pattern_entries = match glob(&pattern) {
			Ok(entries) => entries,
			Err(error) => {
				return Err(anyhow::anyhow!("Error parsing glob pattern '{pattern}': {error}"));
			}
		};

		entries.extend(pattern_entries.flatten());
	}

	if entries.is_empty() {
		return Err(anyhow::anyhow!("No files found"));
	}

	let mut failed = false;

	for entry in entries {
		let file_content = match tokio::fs::read_to_string(entry.clone()).await {
			Ok(content) => content,
			Err(error) => {
				println!("{}: FAIL", entry.display());
				println!("Failed to read file '{}': {error}", entry.display());
				failed = true;
				continue;
			}
		};

		match syn::parse(&file_content) {
			Ok(_) => {
				println!("{}: OK", entry.display());
				println!();
			}
			Err(error) => {
				println!("{}: FAIL", entry.display());
				println!("{error}");
				failed = true;
			}
		}
	}

	if failed {
		return Err(anyhow::anyhow!("Some queries failed to validate"));
	}

	Ok(())
}