Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slow as turtle #33

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
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
2,875 changes: 2,875 additions & 0 deletions projects/ssddOnTop/Cargo.lock

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions projects/ssddOnTop/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[package]
name = "ssddOnTop"
version = "0.1.0"
edition = "2021"

[dependencies]
macros = {path = "./macros"}
macros_common = {path = "./macros-common"}
tokio = {version = "1.40.0", features = ["full"]}
tracing = "0.1.40"
hyper = {version = "1.4.1",features = ["http1","server"]}
hyper-util = {version = "0.1.8", features = ["tokio"]}
http-body-util = "0.1.2"
bytes = "1.7.1"
anyhow = "1.0.87"
async-graphql = {version = "7.0.9", features = ["dynamic-schema"]}
serde_json = "1.0.127"
serde = { version = "1.0.210", features = ["derive"] }
async-graphql-value = "7.0.9"
serde_path_to_error = "0.1.16"
num_cpus = "1.16.0"
reqwest = "0.11"
nom = "7.1.3"
serde_json_borrow = "0.6.0"
derive-getters = "0.5.0"
indexmap = "2.5.0"
derive_more = "0.99.18"
indenter = "0.3.3"
derive_setters = "0.1.6"
fxhash = "0.2.1"
strum_macros = "0.26.4"
http-cache-reqwest = { version = "0.13.0", features = [
"manager-moka",
], default-features = false }
reqwest-middleware = "0.2.5"
http-cache-semantics = { version = "1.0.1", default-features = false, features = ["with_serde", "reqwest"]}
moka = { version = "0.12.7", default-features = false, features = [
"future",
]}
async-trait = "0.1.82"
ttl_cache = "0.5.1"
futures-util = "0.3.30"
http = "1.1.0"
url = "2.5.2"
schemars = {version = "0.8.17", features = ["derive"]}

[dev-dependencies]
http-cache = "0.18.0"

[workspace]
members = []
8 changes: 8 additions & 0 deletions projects/ssddOnTop/macros-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "macros_common"
version = "0.1.0"
edition = "2021"

[dependencies]
async-graphql = "7.0.9"
schemars = { version = "0.8.17" }
42 changes: 42 additions & 0 deletions projects/ssddOnTop/macros-common/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use async_graphql::{Pos, Positioned};
use schemars::schema::SchemaObject;

pub fn get_description(schema: &SchemaObject) -> Option<&String> {
schema
.metadata
.as_ref()
.and_then(|metadata| metadata.description.as_ref())
}

pub fn first_char_to_upper(name: &mut String) {
if let Some(first_char) = name.chars().next() {
// Remove the first character and make it uppercase
let first_char_upper = first_char.to_uppercase().to_string();

// Remove the first character from the original string
let mut chars = name.chars();
chars.next();

// Replace the original string with the new one
*name = first_char_upper + chars.as_str();
}
}

pub fn first_char_to_lower(name: &str) -> String {
if let Some(first_char) = name.chars().next() {
// Remove the first character and make it uppercase
let first_char_upper = first_char.to_lowercase().to_string();

// Remove the first character from the original string
let mut chars = name.chars();
chars.next();

return format!("{}{}", first_char_upper, chars.collect::<String>());
}

String::new()
}

pub fn pos<A>(a: A) -> Positioned<A> {
Positioned::new(a, Pos::default())
}
93 changes: 93 additions & 0 deletions projects/ssddOnTop/macros-common/src/directive_definition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::collections::{BTreeMap, HashSet};

use async_graphql::parser::types::{DirectiveLocation, TypeSystemDefinition};
use async_graphql::Name;
use schemars::schema::{RootSchema, Schema, SchemaObject};

use crate::common::{first_char_to_lower, first_char_to_upper, get_description, pos};
use crate::enum_definition::{into_enum_definition, into_enum_value};
use crate::input_definition::{into_input_definition, into_input_value_definition};

pub trait DirectiveDefinition {
fn directive_definition(generated_types: &mut HashSet<String>) -> Vec<TypeSystemDefinition>;
}

#[derive(Clone)]
pub struct Attrs {
pub name: &'static str,
pub repeatable: bool,
pub locations: Vec<&'static str>,
pub is_lowercase_name: bool,
}

pub fn from_directive_location(str: DirectiveLocation) -> String {
match str {
DirectiveLocation::Schema => String::from("SCHEMA"),
DirectiveLocation::Object => String::from("OBJECT"),
DirectiveLocation::FieldDefinition => String::from("FIELD_DEFINITION"),
DirectiveLocation::EnumValue => String::from("ENUM_VALUE"),
_ => String::from("FIELD_DEFINITION"),
}
}

fn into_directive_location(str: &str) -> DirectiveLocation {
match str {
"Schema" => DirectiveLocation::Schema,
"Object" => DirectiveLocation::Object,
"FieldDefinition" => DirectiveLocation::FieldDefinition,
"EnumValue" => DirectiveLocation::EnumValue,
_ => DirectiveLocation::FieldDefinition,
}
}

pub fn into_directive_definition(
root_schema: RootSchema,
attrs: Attrs,
generated_types: &mut HashSet<String>,
) -> Vec<TypeSystemDefinition> {
let mut service_doc_definitions = vec![];
let definitions: BTreeMap<String, Schema> = root_schema.definitions;
let schema: SchemaObject = root_schema.schema;
let description = get_description(&schema);

for (mut name, schema) in definitions.into_iter() {
if generated_types.contains(&name) {
continue;
}
// the definition could either be an enum or a type
// we don't know which one is it, so we first try to get an EnumValue
// if into_enum_value return Some we can be sure it's an Enum
if let Some(enum_values) = into_enum_value(&schema) {
service_doc_definitions.push(into_enum_definition(enum_values, &name));
generated_types.insert(name.to_string());
} else {
generated_types.insert(name.to_string());
first_char_to_upper(&mut name);
service_doc_definitions.push(into_input_definition(
schema.clone().into_object(),
name.as_str(),
));
}
}

let name = if attrs.is_lowercase_name {
attrs.name.to_lowercase()
} else {
first_char_to_lower(attrs.name)
};

let directve_definition =
TypeSystemDefinition::Directive(pos(async_graphql::parser::types::DirectiveDefinition {
description: description.map(|inner| pos(inner.clone())),
name: pos(Name::new(name)),
arguments: into_input_value_definition(&schema),
is_repeatable: attrs.repeatable,
locations: attrs
.locations
.into_iter()
.map(|val| pos(into_directive_location(val)))
.collect(),
}));
service_doc_definitions.push(directve_definition);
service_doc_definitions
}
58 changes: 58 additions & 0 deletions projects/ssddOnTop/macros-common/src/enum_definition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use async_graphql::parser::types::{
EnumType, EnumValueDefinition, TypeDefinition, TypeKind, TypeSystemDefinition,
};
use async_graphql::{Name, Positioned};
use schemars::schema::Schema;

#[derive(Debug)]
pub struct EnumValue {
pub variants: Vec<String>,
pub description: Option<Positioned<String>>,
}

use crate::common::{get_description, pos};

pub fn into_enum_definition(enum_value: EnumValue, name: &str) -> TypeSystemDefinition {
let mut enum_value_definition = vec![];
for enum_value in enum_value.variants {
let formatted_value: String = enum_value
.to_string()
.chars()
.filter(|ch| ch != &'"')
.collect();
enum_value_definition.push(pos(EnumValueDefinition {
value: pos(Name::new(formatted_value)),
description: None,
directives: vec![],
}));
}

TypeSystemDefinition::Type(pos(TypeDefinition {
name: pos(Name::new(name)),
kind: TypeKind::Enum(EnumType {
values: enum_value_definition,
}),
description: enum_value.description,
directives: vec![],
extend: false,
}))
}

pub fn into_enum_value(obj: &Schema) -> Option<EnumValue> {
match obj {
Schema::Object(schema_object) => {
let description = get_description(schema_object);
if let Some(enum_values) = &schema_object.enum_values {
return Some(EnumValue {
variants: enum_values
.iter()
.map(|val| val.to_string())
.collect::<Vec<String>>(),
description: description.map(|description| pos(description.to_owned())),
});
}
None
}
_ => None,
}
}
Loading