mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
Build derive keys for derivable records
This commit is contained in:
parent
275391c065
commit
aa5e1e6a27
@ -22,6 +22,7 @@ pub(crate) fn derive_decoder(
|
||||
) -> DerivedBody {
|
||||
let (body, body_type) = match key {
|
||||
FlatDecodableKey::List() => decoder_list(env, def_symbol),
|
||||
FlatDecodableKey::Record(_) => todo!(),
|
||||
};
|
||||
|
||||
let specialization_lambda_sets =
|
||||
|
@ -1,7 +1,10 @@
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_types::subs::{Content, FlatType, Subs, Variable};
|
||||
use roc_module::{ident::Lowercase, symbol::Symbol};
|
||||
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||
|
||||
use crate::DeriveError;
|
||||
use crate::{
|
||||
util::{check_empty_ext_var, debug_name_record},
|
||||
DeriveError,
|
||||
};
|
||||
|
||||
#[derive(Hash)]
|
||||
pub enum FlatDecodable {
|
||||
@ -12,12 +15,16 @@ pub enum FlatDecodable {
|
||||
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum FlatDecodableKey {
|
||||
List(/* takes one variable */),
|
||||
|
||||
// Unfortunate that we must allocate here, c'est la vie
|
||||
Record(Vec<Lowercase>),
|
||||
}
|
||||
|
||||
impl FlatDecodableKey {
|
||||
pub(crate) fn debug_name(&self) -> String {
|
||||
match self {
|
||||
FlatDecodableKey::List() => "list".to_string(),
|
||||
FlatDecodableKey::Record(fields) => debug_name_record(fields),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,8 +40,24 @@ impl FlatDecodable {
|
||||
Symbol::STR_STR => Ok(Immediate(Symbol::DECODE_STRING)),
|
||||
_ => Err(Underivable),
|
||||
},
|
||||
FlatType::Record(_fields, _ext) => {
|
||||
Err(Underivable) // yet
|
||||
FlatType::Record(fields, ext) => {
|
||||
check_empty_ext_var(subs, ext, |ext| {
|
||||
matches!(ext, Content::Structure(FlatType::EmptyRecord))
|
||||
})?;
|
||||
|
||||
if subs
|
||||
.get_subs_slice(fields.record_fields())
|
||||
.iter()
|
||||
.any(|f| f.is_optional())
|
||||
{
|
||||
return Err(Underivable);
|
||||
}
|
||||
|
||||
let mut field_names: Vec<_> =
|
||||
subs.get_subs_slice(fields.field_names()).to_vec();
|
||||
field_names.sort();
|
||||
|
||||
Ok(Key(FlatDecodableKey::Record(field_names)))
|
||||
}
|
||||
FlatType::TagUnion(_tags, _ext) | FlatType::RecursiveTagUnion(_, _tags, _ext) => {
|
||||
Err(Underivable) // yet
|
||||
|
@ -4,7 +4,10 @@ use roc_module::{
|
||||
};
|
||||
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
|
||||
|
||||
use crate::{util::check_empty_ext_var, DeriveError};
|
||||
use crate::{
|
||||
util::{check_empty_ext_var, debug_name_record},
|
||||
DeriveError,
|
||||
};
|
||||
|
||||
#[derive(Hash)]
|
||||
pub enum FlatEncodable {
|
||||
@ -28,17 +31,7 @@ impl FlatEncodableKey {
|
||||
FlatEncodableKey::List() => "list".to_string(),
|
||||
FlatEncodableKey::Set() => "set".to_string(),
|
||||
FlatEncodableKey::Dict() => "dict".to_string(),
|
||||
FlatEncodableKey::Record(fields) => {
|
||||
let mut str = String::from('{');
|
||||
fields.iter().enumerate().for_each(|(i, f)| {
|
||||
if i > 0 {
|
||||
str.push(',');
|
||||
}
|
||||
str.push_str(f.as_str());
|
||||
});
|
||||
str.push('}');
|
||||
str
|
||||
}
|
||||
FlatEncodableKey::Record(fields) => debug_name_record(fields),
|
||||
FlatEncodableKey::TagUnion(tags) => {
|
||||
let mut str = String::from('[');
|
||||
tags.iter().enumerate().for_each(|(i, (tag, arity))| {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use roc_module::ident::Lowercase;
|
||||
use roc_types::subs::{Content, Subs, Variable};
|
||||
|
||||
use crate::DeriveError;
|
||||
@ -17,3 +18,15 @@ pub(crate) fn check_empty_ext_var(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn debug_name_record(fields: &[Lowercase]) -> String {
|
||||
let mut str = String::from('{');
|
||||
fields.iter().enumerate().for_each(|(i, f)| {
|
||||
if i > 0 {
|
||||
str.push(',');
|
||||
}
|
||||
str.push_str(f.as_str());
|
||||
});
|
||||
str.push('}');
|
||||
str
|
||||
}
|
||||
|
@ -102,6 +102,10 @@ impl<T> RecordField<T> {
|
||||
RigidOptional(t) => RigidOptional(f(t)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_optional(&self) -> bool {
|
||||
matches!(self, RecordField::Optional(..))
|
||||
}
|
||||
}
|
||||
|
||||
impl RecordField<Type> {
|
||||
|
Loading…
Reference in New Issue
Block a user