Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["codegen", "examples", "performance_measurement", "performance_measur

[package]
name = "worktable"
version = "0.9.0-beta0.1.4"
version = "0.9.0-beta0.2.0"
edition = "2024"
authors = ["Handy-caT"]
license = "MIT"
Expand All @@ -19,9 +19,9 @@ s3-support = ["dep:rusty-s3", "dep:url", "dep:reqwest", "dep:walkdir", "worktabl
[dependencies]
async-trait = "0.1.89"
convert_case = "0.6.0"
data_bucket = "=0.3.14"
data_bucket = "=0.3.15"
# data_bucket = { git = "https://github.com/pathscale/DataBucket", branch = "page_cdc_correction", version = "0.2.7" }
# data_bucket = { path = "../DataBucket", version = "0.3.11" }
# data_bucket = { path = "../DataBucket", version = "0.3.14" }
derive_more = { version = "2.0.1", features = ["from", "error", "display", "debug", "into"] }
eyre = "0.6.12"
fastrand = "2.3.0"
Expand All @@ -46,7 +46,7 @@ tracing = "0.1"
url = { version = "2", optional = true }
uuid = { version = "1.10.0", features = ["v4", "v7"] }
walkdir = { version = "2", optional = true }
worktable_codegen = { path = "codegen", version = "=0.9.0-beta0.1.3" }
worktable_codegen = { path = "codegen", version = "=0.9.0-beta0.2.0" }

[dev-dependencies]
chrono = "0.4.43"
Expand Down
2 changes: 1 addition & 1 deletion codegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "worktable_codegen"
version = "0.9.0-beta0.1.3"
version = "0.9.0-beta0.2.0"
edition = "2024"
license = "MIT"
description = "WorkTable codegeneration crate"
Expand Down
7 changes: 7 additions & 0 deletions codegen/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod model;
pub mod name_generator;
pub mod parser;

#[allow(unused_imports)]
pub use model::*;
pub use parser::Parser;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use indexmap::IndexMap;
use std::collections::HashMap;

use crate::worktable::model::GeneratorType;
use crate::worktable::model::index::Index;
use crate::common::model::GeneratorType;
use crate::common::model::index::Index;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::spanned::Spanned;
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use proc_macro2::Ident;

use crate::worktable::model::Operation;
use crate::common::model::Operation;

#[derive(Debug, Default)]
pub struct Queries {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ impl WorktableNameGenerator {
Self { name }
}

pub fn get_dir_name(&self) -> String {
self.name.from_case(Case::Pascal).to_case(Case::Snake)
}

pub fn get_update_query_lock_ident(snake_case_name: &String) -> Ident {
Ident::new(
format!("lock_update_{snake_case_name}").as_str(),
Span::mixed_site(),
)
}

pub fn get_update_in_place_query_lock_ident(snake_case_name: &String) -> Ident {
Ident::new(
format!("lock_update_in_place_{snake_case_name}").as_str(),
Span::mixed_site(),
)
}

pub fn get_work_table_literal_name(&self) -> Literal {
Literal::string(self.name.as_str())
}
Expand Down Expand Up @@ -118,6 +136,14 @@ impl WorktableNameGenerator {
)
}

pub fn get_version_const_ident(&self) -> Ident {
let upper_snake_case_name = self.name.from_case(Case::Pascal).to_case(Case::UpperSnake);
Ident::new(
format!("{}_VERSION", upper_snake_case_name.to_uppercase()).as_str(),
Span::mixed_site(),
)
}

pub fn get_space_secondary_index_ident(&self) -> Ident {
Ident::new(
format!("{}SpaceSecondaryIndex", self.name).as_str(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::TokenTree;
use syn::spanned::Spanned as _;

use crate::worktable::parser::Parser;
use crate::common::parser::Parser;

// TODO: Move this to separate attributes section because now it only parses persist.
impl Parser {
Expand Down Expand Up @@ -45,7 +45,7 @@ impl Parser {
mod tests {
use quote::quote;

use crate::worktable::Parser;
use crate::common::Parser;

#[test]
fn test_empty() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use proc_macro2::{Delimiter, TokenTree};
use syn::spanned::Spanned as _;

use crate::worktable::Parser;
use crate::worktable::model::{Columns, GeneratorType, Row};
use crate::common::Parser;
use crate::common::model::{Columns, GeneratorType, Row};

impl Parser {
pub fn parse_columns(&mut self) -> syn::Result<Columns> {
Expand Down Expand Up @@ -132,7 +132,7 @@ mod tests {

use quote::quote;

use crate::worktable::Parser;
use crate::common::Parser;

#[test]
fn test_columns_parse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::str::FromStr;
use proc_macro2::{Delimiter, TokenTree};
use syn::spanned::Spanned;

use crate::worktable::Parser;
use crate::worktable::model::Config;
use crate::common::Parser;
use crate::common::model::Config;

const CONFIG_FIELD_NAME: &str = "config";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::worktable::Parser;
use crate::worktable::model::Index;
use crate::common::Parser;
use crate::common::model::Index;
use indexmap::IndexMap;
use proc_macro2::{Delimiter, Ident, TokenTree};
use syn::spanned::Spanned;
Expand Down
File renamed without changes.
159 changes: 159 additions & 0 deletions codegen/src/common/parser/name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
use proc_macro2::Ident;
use proc_macro2::TokenTree;
use syn::spanned::Spanned as _;

use crate::common::parser::Parser;

impl Parser {
pub fn parse_name(&mut self) -> syn::Result<Ident> {
let ident = self.input_iter.next().ok_or(syn::Error::new(
self.input.span(),
"Expected `name` field in declaration",
))?;
if let TokenTree::Ident(ident) = ident {
if ident.to_string().as_str() != "name" {
return Err(syn::Error::new(
ident.span(),
"Expected `name` field. `WorkTable` name must be specified",
));
}
} else {
return Err(syn::Error::new(
ident.span(),
"Expected field name identifier.",
));
};

self.parse_colon()?;

let name = self
.input_iter
.next()
.ok_or(syn::Error::new(self.input.span(), "Expected token."))?;
let name = if let TokenTree::Ident(name) = name {
name
} else {
return Err(syn::Error::new(name.span(), "Expected identifier."));
};

self.try_parse_comma()?;

Ok(name)
}

pub fn parse_version(&mut self) -> syn::Result<Option<u32>> {
if let Some(ident) = self.peek_next()
&& ident.to_string().as_str() == "version" {
self.input_iter.next();

self.parse_colon()?;

let value = self.input_iter.next().ok_or(syn::Error::new(
self.input.span(),
"Expected version value",
))?;
let value = if let TokenTree::Literal(value) = value {
value
} else {
return Err(syn::Error::new(value.span(), "Expected literal for version."));
};

self.try_parse_comma()?;

let value_str = value.to_string().replace("_", "");
let version = value_str.parse::<u32>().map_err(|_| {
syn::Error::new(value.span(), "Expected valid u32 number for version.")
})?;

return Ok(Some(version));
}
Ok(None)
}
}

#[cfg(test)]
mod tests {
use quote::quote;

use crate::common::Parser;

#[test]
fn test_name_parse() {
let tokens = quote! {name: TestName,};

let mut parser = Parser::new(tokens);
let name = parser.parse_name();

assert!(name.is_ok());
let name = name.unwrap();

assert_eq!(name, "TestName");
}

#[test]
fn test_empty() {
let tokens = quote! {};

let mut parser = Parser::new(tokens);
let name = parser.parse_name();

assert!(name.is_err());
}

#[test]
fn test_literal_field() {
let tokens = quote! {"nme": TestName,};

let mut parser = Parser::new(tokens);
let name = parser.parse_name();

assert!(name.is_err());
}

#[test]
fn test_wrong_field() {
let tokens = quote! {nme: TestName,};

let mut parser = Parser::new(tokens);
let name = parser.parse_name();

assert!(name.is_err());
}

#[test]
fn test_version_parse() {
let tokens = quote! {name: TestName, version: 2,};

let mut parser = Parser::new(tokens);
let name = parser.parse_name().unwrap();
assert_eq!(name, "TestName");

let version = parser.parse_version().unwrap();
assert_eq!(version, Some(2));
}

#[test]
fn test_version_default() {
let tokens = quote! {name: TestName,};

let mut parser = Parser::new(tokens);
let name = parser.parse_name().unwrap();
assert_eq!(name, "TestName");

let version = parser.parse_version().unwrap();
assert_eq!(version, None);
}

#[test]
fn test_version_before_other_fields() {
let tokens = quote! {name: TestName, version: 5, columns: { id: u64 primary_key },};

let mut parser = Parser::new(tokens);
let name = parser.parse_name().unwrap();
let version = parser.parse_version().unwrap();
assert_eq!(version, Some(5));

let next = parser.peek_next().unwrap();
assert_eq!(next.to_string(), "columns");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::TokenTree;
use syn::spanned::Spanned;

use crate::worktable::parser::Parser;
use crate::common::parser::Parser;

impl Parser {
/// Parses ':' from [`proc_macro2::TokenStream`].
Expand Down Expand Up @@ -37,6 +37,38 @@ impl Parser {

Ok(())
}

/// Parses '=>' from token stream.
pub fn parse_fat_arrow(&mut self) -> syn::Result<()> {
let iter = &mut self.input_iter;

let first = iter
.next()
.ok_or(syn::Error::new(self.input.span(), "Expected token."))?;
if let TokenTree::Punct(p) = first {
if p.as_char() == '=' {
// next should be '>'
let second = iter
.next()
.ok_or(syn::Error::new(self.input.span(), "Expected '>' after '='"))?;
if let TokenTree::Punct(p2) = second {
if p2.as_char() == '>' {
return Ok(());
}
return Err(syn::Error::new(
p2.span(),
format!("Expected '>' found: '{}'", p2.as_char()),
));
}
return Err(syn::Error::new(second.span(), "Expected '>'"));
}
return Err(syn::Error::new(
p.span(),
format!("Expected '=' found: '{}'", p.as_char()),
));
}
Err(syn::Error::new(first.span(), "Expected '=>'"))
}
}

fn comma(tt: &TokenTree) -> syn::Result<()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::collections::HashMap;
use proc_macro2::{Ident, TokenTree};
use syn::spanned::Spanned;

use crate::worktable::Parser;
use crate::worktable::model::Operation;
use crate::common::Parser;
use crate::common::model::Operation;

impl Parser {
pub fn parse_deletes(&mut self) -> syn::Result<HashMap<Ident, Operation>> {
Expand Down Expand Up @@ -46,7 +46,7 @@ mod tests {
use proc_macro2::{Ident, Span};
use quote::quote;

use crate::worktable::Parser;
use crate::common::Parser;

#[test]
fn test_update() {
Expand Down
Loading
Loading