spyglass_cli/
lib.rs

1use anyhow::{format_err, Context};
2use clap::Parser;
3use pb::sf::substreams::v1::Package;
4use prost::Message;
5use reqwest;
6
7mod parser;
8pub mod graphql_types;
9pub mod pb;
10pub mod codegen;
11
12#[derive(Parser, Debug)]
13#[command(author, version, about)]
14pub struct Cli {
15    #[clap(subcommand)]
16    pub command: Commands,
17}
18
19#[derive(Parser, Debug)]
20pub enum Commands {
21    Generate {
22        #[arg(index = 1)]
23        spkg_path: String,
24        #[arg(short, long, default_value = "./src/spyglass/")]
25        output_dir: String,
26    },
27}
28
29#[derive(Debug)]
30pub struct MyPackage(Package);
31
32impl MyPackage{
33
34    pub fn package(self) -> Package {
35        self.0
36    }
37
38    pub async fn new(input: &str) -> Result<Self, anyhow::Error> {
39        let package = Self::read_package(input).await?;
40        Ok(Self(package))
41    }
42
43    async fn read_package(input: &str) -> Result<Package, anyhow::Error> {
44        if input.starts_with("http") {
45            return Self::read_http_package(input).await;
46        }
47
48        // Assume it's a local file
49
50        let content =
51            std::fs::read(input).context(format_err!("read package from file '{}'", input))?;
52        Package::decode(content.as_ref()).context("decode command")
53    }
54
55async fn read_http_package(input: &str) -> Result<Package, anyhow::Error> {
56    let body = reqwest::get(input).await?.bytes().await?;
57
58    Package::decode(body).context("decode command")
59}
60}