1use std::{io, path::Path};
2
3use interstice_core::IntersticeError;
4
5pub fn init() -> Result<(), IntersticeError> {
11 println!("Enter the project name: ");
12 let project_name = &mut String::new();
13 io::stdin()
14 .read_line(project_name)
15 .expect("Should be able to read line");
16 let project_name = project_name
17 .parse::<String>()
18 .map_err(|_| IntersticeError::Internal("Failed to read project name".into()))?
19 .trim()
20 .to_string();
21 let project_path = Path::new(&project_name);
22 if project_path.exists() {
23 return Err(IntersticeError::Internal("Directory already exists".into()));
24 }
25 std::fs::create_dir(&project_path).map_err(|err| {
26 IntersticeError::Internal(format!("Failed to create project directory: {}", err))
27 })?;
28
29 let name = project_name.to_lowercase();
30
31 let cargo_toml_content = format!(
33 r#"[package]
34name = "{name}"
35version = "0.1.0"
36edition = "2024"
37
38[lib]
39crate-type = ["cdylib"]
40
41[dependencies]
42interstice_sdk = "0.1.0"
43
44[build-dependencies]
45interstice_sdk = "0.1.0"
46"#,
47 );
48 std::fs::write(project_path.join("Cargo.toml"), cargo_toml_content).map_err(|err| {
49 IntersticeError::Internal(format!("Failed to create Cargo.toml: {}", err))
50 })?;
51
52 let cargo_config_content = r#"[build]
54target = "wasm32-unknown-unknown"
55"#;
56 std::fs::create_dir(project_path.join(".cargo")).map_err(|err| {
57 IntersticeError::Internal(format!("Failed to create .cargo directory: {}", err))
58 })?;
59 std::fs::write(
60 project_path.join(".cargo/config.toml"),
61 cargo_config_content,
62 )
63 .map_err(|err| {
64 IntersticeError::Internal(format!("Failed to create .cargo/config.toml: {}", err))
65 })?;
66
67 let build_rs_content = r#"fn main() {
69 interstice_sdk::bindings::generate_bindings();
70}
71"#;
72 std::fs::create_dir(project_path.join("src")).map_err(|err| {
73 IntersticeError::Internal(format!("Failed to create src directory: {}", err))
74 })?;
75 std::fs::write(project_path.join("build.rs"), build_rs_content)
76 .map_err(|err| IntersticeError::Internal(format!("Failed to create build.rs: {}", err)))?;
77
78 let lib_content = r#"use interstice_sdk::*;
80
81interstice_module!(visibility: Public);
82
83// TABLES
84
85#[table(public)]
86#[derive(Debug)]
87pub struct Greetings {
88 #[primary_key]
89 pub id: u64,
90 pub greeting: String,
91 pub custom: TestCustomType,
92}
93
94#[interstice_type]
95#[derive(Debug, Clone)]
96pub struct TestCustomType {
97 pub val: u32,
98}
99
100// REDUCERS
101#[reducer(on = "init")]
102pub fn init(ctx: ReducerContext) {
103 ctx.log("Hello world !");
104}
105
106#[reducer]
107pub fn hello(ctx: ReducerContext, name: String) {
108 ctx.log(&format!("Saying hello to {}", name));
109 ctx.current.greetings().insert(Greetings {
110 id: 0,
111 greeting: format!("Hello, {}!", name),
112 custom: TestCustomType { val: 0 },
113 });
114}
115
116#[reducer(on = "hello.greetings.insert")]
117fn on_greeting_insert(ctx: ReducerContext, inserted_row: Greetings) {
118 ctx.log(&format!("Inserted greeting: {:?}", inserted_row));
119}"#;
120
121 std::fs::write(project_path.join("src/lib.rs"), lib_content).map_err(|err| {
122 IntersticeError::Internal(format!("Failed to create src/lib.rs: {}", err))
123 })?;
124 Ok(())
125}