Skip to content

Commit

Permalink
use safe_cell
Browse files Browse the repository at this point in the history
  • Loading branch information
obmarg committed Sep 18, 2023
1 parent 63b105d commit a8d0e9e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 95 deletions.
76 changes: 9 additions & 67 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion cynic-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ counter = "0.5"
darling.workspace = true
graphql-parser = "0.4.0"
once_cell = "1.9.0"
ouroboros = "0.18"
proc-macro2 = "1.0"
quote = "1.0"
self_cell = { version = "1" }
strsim = "0.10.0"
syn = { workspace = true , features = ["visit-mut"] }
thiserror = "1"

# Optional deps
rkyv = { version = "0.7.41", features = ["validation"], optional = true }

[dev-dependencies]
Expand Down
41 changes: 29 additions & 12 deletions cynic-codegen/src/schema/type_index/optimised.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::collections::HashMap;

use rkyv::Deserialize;
use self_cell::self_cell;

use crate::schema::{
self,
Expand Down Expand Up @@ -31,19 +32,35 @@ impl Schema<'_, schema::Validated> {
}
}

#[ouroboros::self_referencing]
self_cell! {
struct AstCell {
owner: Vec<u8>,

#[covariant]
dependent: ArchiveRef,
}
}

type ArchiveRef<'a> = &'a ArchivedOptimisedTypes<'static>;

pub struct ArchiveBacked {
data: Vec<u8>,
#[borrows(data)]
archived: &'this ArchivedOptimisedTypes<'static>,
data: AstCell,
}

impl ArchiveBacked {
pub fn from_checked_data(data: Vec<u8>) -> Self {
ArchiveBacked::new(data, |data| unsafe {
// This is safe so long as we've already verified data
rkyv::archived_root::<OptimisedTypes<'_>>(&data[..])
})
ArchiveBacked {
data: AstCell::new(data, |data| {
unsafe {
// This is safe so long as we've already verified data
rkyv::archived_root::<OptimisedTypes<'_>>(&data[..])
}
}),
}
}

fn archive(&self) -> ArchiveRef<'_> {
self.data.borrow_dependent()
}
}

Expand All @@ -55,7 +72,7 @@ impl super::TypeIndex for ArchiveBacked {

fn lookup_valid_type<'a>(&'a self, name: &str) -> Result<Type<'a>, SchemaError> {
Ok(self
.borrow_archived()
.archive()
.types
.get(name)
.ok_or_else(|| SchemaError::CouldNotFindType {
Expand All @@ -67,15 +84,15 @@ impl super::TypeIndex for ArchiveBacked {

fn root_types(&self) -> Result<schema::types::SchemaRoots<'_>, SchemaError> {
Ok(self
.borrow_archived()
.archive()
.schema_roots
.deserialize(&mut rkyv::Infallible)
.expect("infallible"))
}

fn unsafe_lookup<'a>(&'a self, name: &str) -> Option<Type<'a>> {
Some(
self.borrow_archived()
self.archive()
.types
.get(name)
.unwrap()
Expand All @@ -85,7 +102,7 @@ impl super::TypeIndex for ArchiveBacked {
}

fn unsafe_iter<'a>(&'a self) -> Box<dyn Iterator<Item = Type<'a>> + 'a> {
Box::new(self.borrow_archived().types.values().map(|archived_type| {
Box::new(self.archive().types.values().map(|archived_type| {
archived_type
.deserialize(&mut rkyv::Infallible)
.expect("infallible")
Expand Down
39 changes: 24 additions & 15 deletions cynic-codegen/src/schema/type_index/schema_backed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{
};

use once_cell::sync::Lazy;
use self_cell::self_cell;

use crate::schema::{
names::FieldName,
Expand All @@ -13,15 +14,22 @@ use crate::schema::{
SchemaError,
};

#[ouroboros::self_referencing]
type TypeMap<'a> = HashMap<&'a str, &'a TypeDefinition>;

self_cell! {
struct DocumentCell {
owner: Document,

#[covariant]
dependent: TypeMap,
}
}

pub struct SchemaBackedTypeIndex {
document: Document,
query_root: String,
mutation_root: Option<String>,
subscription_root: Option<String>,
#[borrows(document)]
#[covariant]
types: HashMap<&'this str, &'this TypeDefinition>,
data: DocumentCell,
}

impl SchemaBackedTypeIndex {
Expand All @@ -41,12 +49,11 @@ impl SchemaBackedTypeIndex {
}
}

SchemaBackedTypeIndex::new(
document,
SchemaBackedTypeIndex {
query_root,
mutation_root,
subscription_root,
|document| {
data: DocumentCell::new(document, |document| {
let mut types = HashMap::new();
for definition in &document.definitions {
if let Definition::TypeDefinition(type_def) = definition {
Expand All @@ -57,8 +64,12 @@ impl SchemaBackedTypeIndex {
types.insert(name_for_type(def), def);
}
types
},
)
}),
}
}

fn borrow_types(&self) -> &HashMap<&str, &TypeDefinition> {
self.data.borrow_dependent()
}
}

Expand All @@ -82,17 +93,15 @@ impl super::TypeIndex for SchemaBackedTypeIndex {

fn root_types(&self) -> Result<SchemaRoots<'_>, SchemaError> {
Ok(SchemaRoots {
query: self
.lookup_valid_type(self.borrow_query_root())?
.try_into()?,
query: self.lookup_valid_type(&self.query_root)?.try_into()?,
mutation: self
.borrow_mutation_root()
.mutation_root
.as_ref()
.map(|name| ObjectType::try_from(self.lookup_valid_type(name)?))
.transpose()?
.or_else(|| ObjectType::try_from(self.lookup_valid_type("Mutation").ok()?).ok()),
subscription: self
.borrow_subscription_root()
.subscription_root
.as_ref()
.map(|name| ObjectType::try_from(self.lookup_valid_type(name)?))
.transpose()?
Expand Down

0 comments on commit a8d0e9e

Please sign in to comment.