« Back to Index

Rust: Basic parsing of go.mod with Rust

View original Gist on GitHub

Tags: #rust #go #serialization

Cargo.toml

[package]
name = "testing-parse-gomod"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
semver = "1.0.4"

go.mod

module whatever

go 1.18

require example.com/foo/bar v1.0.0
require example.com/foo/bar/v2 v2.0.0

require (
    example.com/beep/boop v3.0.0
    example.com/quick/quack v4.0.0
)

require (
    example.com/something/else v5.0.0
)

main.rs

// https://go.dev/ref/mod#go-mod-file-require
// https://go.dev/ref/mod#pseudo-versions

use semver::Version;

type AvailableDependency = (String, Version, Vec<String>);

const GO_MOD: &str = include_str!("../go.mod");

fn main() {
    let mut block = false;
    let deps: Vec<AvailableDependency> = GO_MOD
        .lines()
        .filter_map(|v| {
            let segs: Vec<&str> = v.split(' ').collect();
            if segs.len() == 1 {
                if segs[0] == ")" {
                    block = false;
                }
                return None;
            }
            if block {
                let nested_dep: Vec<_> = segs.iter().filter(|v| !v.is_empty()).collect();
                let mut version = nested_dep[1].chars();
                version.next();

                return Some((
                    nested_dep[0].to_string(),
                    Version::parse(version.as_str())
                        .expect("could not parse default dependency version"),
                    vec![],
                ));
            }
            if segs[0] == "require" {
                if segs[1] == "(" {
                    block = true;
                    return None;
                }

                let slice = &segs[1..];
                let mut version = slice[1].chars();
                version.next();

                return Some((
                    slice[0].to_string(),
                    Version::parse(version.as_str())
                        .expect("could not parse default dependency version"),
                    vec![],
                ));
            }
            None
        })
        .collect();

    println!("{:#?}", deps);
}