Skip to content

Commit

Permalink
feat: rust template
Browse files Browse the repository at this point in the history
  • Loading branch information
Linkinlog committed Feb 27, 2024
1 parent d2acc81 commit ace7bc3
Show file tree
Hide file tree
Showing 18 changed files with 296 additions and 165 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gen-aoc"
version = "0.1.0"
version = "0.1.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## Features

Generates a shiny new project folder for your chosen day of AOC madness
Automates boilerplate code and tests in Go (we're still working on the whole 'multiple languages' thing)

Automates boilerplate code and tests in your language of choice


## Usage (it's so easy, even a reindeer could do it)
Expand All @@ -13,7 +14,7 @@ Automates boilerplate code and tests in Go (we're still working on the whole 'mu
--day: The AOC puzzle you're about to tackle
```
```bash
--lang: Currently only supports go
--lang: Currently only supports go & rust
```
```bash
--fresh: If you want a sparkling clean start, this flag wipes out any existing code
Expand Down
1 change: 1 addition & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clap::Parser;
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Langs {
Go,
Rust,
}

#[derive(Parser)]
Expand Down
163 changes: 9 additions & 154 deletions src/gen.rs
Original file line number Diff line number Diff line change
@@ -1,165 +1,20 @@
use std::fs;
use crate::cli;
use crate::go_gen::GoGen;
use crate::rust_gen::RustGen;

pub struct GoGen {
pub struct Gen {
day: u32,
fresh: bool,
}

impl GoGen {
impl Gen {
pub fn new(day: u32, fresh: bool) -> Self {
Self { day, fresh }
}
pub fn generate(&self) {
println!("Generating Go for day {}", self.day);
let err = fs::create_dir(format!("day{}", self.day));
match err {
Ok(_) => {}
Err(e) => {
if e.kind() == std::io::ErrorKind::AlreadyExists {
if self.fresh {
fs::remove_dir_all(format!("day{}", self.day)).unwrap();
fs::create_dir(format!("day{}", self.day)).unwrap();
} else {
panic!("Directory already exists, use --fresh to overwrite");
}
} else {
panic!("Error creating directory: {}", e);
}
}
pub fn generate(&self, lang: cli::Langs) {
match lang {
cli::Langs::Rust => RustGen::new(self.day, self.fresh).generate(),
cli::Langs::Go => GoGen::new(self.day, self.fresh).generate(),
}
fs::write(format!("day{}/input.txt", self.day), "").unwrap();
fs::write(format!("day{}/go.mod", self.day), Self::GO_MOD_TEMPLATE).unwrap();
fs::write(format!("day{}/main.go", self.day), Self::GO_MAIN_TEMPLATE).unwrap();
fs::write(
format!("day{}/solution.go", self.day),
Self::SOLUTION_TEMPLATE,
)
.unwrap();
fs::write(
format!("day{}/solution_test.go", self.day),
Self::TEST_TEMPLATE,
)
.unwrap();
fs::write(
format!("day{}/solution_benchmark_test.go", self.day),
Self::TEST_BENCHMARK_TEMPLATE,
)
.unwrap();
println!("Generated Go for day {}, Happy Hacking!", self.day);
}

const GO_MOD_TEMPLATE: &'static str = r#"module AdventOfCode
go 1.22
"#;

const GO_MAIN_TEMPLATE: &'static str = r#"package main
import (
_ "embed"
"flag"
"fmt"
"strings"
)
//go:embed input.txt
var input string
func init() {
input = strings.TrimRight(input, "\n")
if len(input) == 0 {
panic("empty input.txt file")
}
}
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Printf("Running part %d...\n", part)
if part == 1 {
ans := part1(input)
fmt.Println(ans)
} else {
ans := part2(input)
fmt.Println(ans)
}
}"#;

const SOLUTION_TEMPLATE: &'static str = r#"package main
import "strings"
func part1(input string) any {
for _, line := range strings.Split(input, "\n") {
_ = line
}
return nil
}
func part2(input string) any {
for _, line := range strings.Split(input, "\n") {
_ = line
}
return nil
}"#;

const TEST_TEMPLATE: &'static str = r#"package main
import "testing"
func TestPart1(t *testing.T) {
tests := []struct {
name string
input string
want any
}{
// TODO
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := part1(tt.input); got != tt.want {
t.Errorf("part1() = %v, want %v", got, tt.want)
}
})
}
}
func TestPart2(t *testing.T) {
tests := []struct {
name string
input string
want any
}{
// TODO
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := part2(tt.input); got != tt.want {
t.Errorf("part2() = %v, want %v", got, tt.want)
}
})
}
}"#;

const TEST_BENCHMARK_TEMPLATE: &'static str = r#"package main
import "testing"
func BenchmarkPart1(b *testing.B) {
for i := 0; i < b.N; i++ {
part1(input)
}
}
func BenchmarkPart2(b *testing.B) {
for i := 0; i < b.N; i++ {
part2(input)
}
}"#;
}
58 changes: 58 additions & 0 deletions src/go_gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use std::fs;

pub struct GoGen {
day: u32,
fresh: bool,
}

impl GoGen {
pub fn new(day: u32, fresh: bool) -> Self {
Self { day, fresh }
}
pub fn generate(&self) {
println!("Generating Go for day {}", self.day);
let err = fs::create_dir(format!("day{}", self.day));
match err {
Ok(_) => {}
Err(e) => {
if e.kind() == std::io::ErrorKind::AlreadyExists {
if self.fresh {
fs::remove_dir_all(format!("day{}", self.day))
.expect("Error removing directory");
fs::create_dir(format!("day{}", self.day))
.expect("Error creating directory");
} else {
panic!("Directory already exists, use --fresh to overwrite");
}
} else {
panic!("Error creating directory: {}", e);
}
}
}
let input =
fs::read_to_string("src/templates/go/input.txt").expect("Error reading input.txt");
let go_mod = fs::read_to_string("src/templates/go/go.mod").expect("Error reading go.mod");
let go_main =
fs::read_to_string("src/templates/go/main.go").expect("Error reading main.go");
let solution =
fs::read_to_string("src/templates/go/solution.go").expect("Error reading solution.go");
let solution_test = fs::read_to_string("src/templates/go/solution_test.go")
.expect("Error reading solution_test.go");
let solution_benchmark_test = fs::read_to_string("src/templates/go/solution_benchmark.go")
.expect("Error reading solution_benchmark.go");

fs::write(format!("day{}/input.txt", self.day), input).expect("Error writing input.txt");
fs::write(format!("day{}/go.mod", self.day), go_mod).expect("Error writing go.mod");
fs::write(format!("day{}/main.go", self.day), go_main).expect("Error writing main.go");
fs::write(format!("day{}/solution.go", self.day), solution)
.expect("Error writing solution.go");
fs::write(format!("day{}/solution_test.go", self.day), solution_test)
.expect("Error writing solution_test.go");
fs::write(
format!("day{}/solution_benchmark_test.go", self.day),
solution_benchmark_test,
)
.expect("Error writing solution_benchmark_test.go");
println!("Generated Go for day {}, Happy Hacking!", self.day);
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod cli;
pub mod gen;
pub mod go_gen;
pub mod rust_gen;
9 changes: 2 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
use gen_aoc::cli::Cli;
use gen_aoc::gen::GoGen;
use gen_aoc::gen::Gen;

fn main() {
let args = Cli::new();
match args.lang() {
gen_aoc::cli::Langs::Go => {
let gen = GoGen::new(args.day(), args.fresh());
gen.generate();
}
}
Gen::new(args.day(), args.fresh()).generate(args.lang());
}
51 changes: 51 additions & 0 deletions src/rust_gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::fs;

pub struct RustGen {
day: u32,
fresh: bool,
}

impl RustGen {
pub fn new(day: u32, fresh: bool) -> Self {
Self { day, fresh }
}
pub fn generate(&self) {
println!("Generating Rust for day {}", self.day);
let err = fs::create_dir(format!("day{}", self.day));
match err {
Ok(_) => {
fs::create_dir(format!("day{}/src", self.day))
.expect("Error creating src directory");
}
Err(e) => {
if e.kind() == std::io::ErrorKind::AlreadyExists {
if self.fresh {
fs::remove_dir_all(format!("day{}", self.day))
.expect("Error removing directory");
fs::create_dir(format!("day{}", self.day))
.expect("Error creating directory");
fs::create_dir(format!("day{}/src", self.day))
.expect("Error creating src directory");
} else {
panic!("Directory already exists, use --fresh to overwrite");
}
} else {
panic!("Error creating directory: {}", e);
}
}
}
let input =
fs::read_to_string("src/templates/rust/input.txt").expect("Error reading input.txt");
let cargo_toml =
fs::read_to_string("src/templates/rust/Cargo.toml").expect("Error reading Cargo.toml");
let main =
fs::read_to_string("src/templates/rust/src/main.rs").expect("Error reading main.rs");

fs::write(format!("day{}/input.txt", self.day), input).expect("Error writing input.txt");
fs::write(format!("day{}/Cargo.toml", self.day), cargo_toml)
.expect("Error writing Cargo.toml");
fs::write(format!("day{}/src/main.rs", self.day), main).expect("Error writing main.rs");

println!("Generated Rust for day {}, Happy Hacking!", self.day);
}
}
4 changes: 4 additions & 0 deletions src/templates/go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module AdventOfCode

go 1.22

Empty file added src/templates/go/input.txt
Empty file.
33 changes: 33 additions & 0 deletions src/templates/go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import (
_ "embed"
"flag"
"fmt"
"strings"
)

//go:embed input.txt
var input string

func init() {
input = strings.TrimRight(input, "\n")
if len(input) == 0 {
panic("empty input.txt file")
}
}

func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Printf("Running part %d...\n", part)

if part == 1 {
ans := part1(input)
fmt.Println(ans)
} else {
ans := part2(input)
fmt.Println(ans)
}
}
Loading

0 comments on commit ace7bc3

Please sign in to comment.