Preserve bytearray format choice from input.
This commit is contained in:
parent
f3cdc05875
commit
98b89f32e1
|
@ -326,11 +326,21 @@ pub struct DefinitionLocation<'module> {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Constant {
|
||||
Int { location: Span, value: String },
|
||||
Int {
|
||||
location: Span,
|
||||
value: String,
|
||||
},
|
||||
|
||||
String { location: Span, value: String },
|
||||
String {
|
||||
location: Span,
|
||||
value: String,
|
||||
},
|
||||
|
||||
ByteArray { location: Span, bytes: Vec<u8> },
|
||||
ByteArray {
|
||||
location: Span,
|
||||
bytes: Vec<u8>,
|
||||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
}
|
||||
|
||||
impl Constant {
|
||||
|
@ -748,6 +758,13 @@ impl<A, B> Pattern<A, B> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum ByteArrayFormatPreference {
|
||||
HexadecimalString,
|
||||
ArrayOfBytes,
|
||||
Utf8String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum AssignmentKind {
|
||||
Let,
|
||||
|
|
|
@ -4,9 +4,9 @@ use vec1::Vec1;
|
|||
|
||||
use crate::{
|
||||
ast::{
|
||||
Annotation, Arg, AssignmentKind, BinOp, CallArg, Clause, DefinitionLocation, IfBranch,
|
||||
Pattern, RecordUpdateSpread, Span, TraceKind, TypedRecordUpdateArg, UnOp,
|
||||
UntypedRecordUpdateArg,
|
||||
Annotation, Arg, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg, Clause,
|
||||
DefinitionLocation, IfBranch, Pattern, RecordUpdateSpread, Span, TraceKind,
|
||||
TypedRecordUpdateArg, UnOp, UntypedRecordUpdateArg,
|
||||
},
|
||||
builtins::void,
|
||||
tipo::{ModuleValueConstructor, PatternConstructor, Type, ValueConstructor},
|
||||
|
@ -361,6 +361,7 @@ pub enum UntypedExpr {
|
|||
ByteArray {
|
||||
location: Span,
|
||||
bytes: Vec<u8>,
|
||||
preferred_format: ByteArrayFormatPreference,
|
||||
},
|
||||
|
||||
PipeLine {
|
||||
|
|
|
@ -5,12 +5,12 @@ use vec1::Vec1;
|
|||
|
||||
use crate::{
|
||||
ast::{
|
||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, ClauseGuard, Constant, DataType,
|
||||
Definition, Function, IfBranch, ModuleConstant, Pattern, RecordConstructor,
|
||||
RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp,
|
||||
UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedDefinition,
|
||||
UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator,
|
||||
CAPTURE_VARIABLE,
|
||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||
ClauseGuard, Constant, DataType, Definition, Function, IfBranch, ModuleConstant, Pattern,
|
||||
RecordConstructor, RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias,
|
||||
TypedArg, UnOp, UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard,
|
||||
UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg,
|
||||
Use, Validator, CAPTURE_VARIABLE,
|
||||
},
|
||||
docvec,
|
||||
expr::{UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
|
||||
|
@ -326,7 +326,11 @@ impl<'comments> Formatter<'comments> {
|
|||
|
||||
fn const_expr<'a>(&mut self, value: &'a Constant) -> Document<'a> {
|
||||
match value {
|
||||
Constant::ByteArray { bytes, .. } => self.bytearray(bytes),
|
||||
Constant::ByteArray {
|
||||
bytes,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(bytes, preferred_format),
|
||||
Constant::Int { value, .. } => value.to_doc(),
|
||||
Constant::String { value, .. } => self.string(value),
|
||||
}
|
||||
|
@ -635,18 +639,40 @@ impl<'comments> Formatter<'comments> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn bytearray<'a>(&mut self, bytes: &'a [u8]) -> Document<'a> {
|
||||
"#".to_doc()
|
||||
pub fn bytearray<'a>(
|
||||
&mut self,
|
||||
bytes: &'a [u8],
|
||||
preferred_format: &ByteArrayFormatPreference,
|
||||
) -> Document<'a> {
|
||||
match preferred_format {
|
||||
ByteArrayFormatPreference::HexadecimalString => "#"
|
||||
.to_doc()
|
||||
.append("\"")
|
||||
.append(Document::String(hex::encode(bytes)))
|
||||
.append("\"")
|
||||
.append("\""),
|
||||
ByteArrayFormatPreference::ArrayOfBytes => "#"
|
||||
.to_doc()
|
||||
.append(
|
||||
flex_break("[", "[")
|
||||
.append(join(bytes.iter().map(|b| b.to_doc()), break_(",", ", ")))
|
||||
.nest(INDENT)
|
||||
.append(break_(",", ""))
|
||||
.append("]"),
|
||||
)
|
||||
.group(),
|
||||
ByteArrayFormatPreference::Utf8String => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expr<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
||||
let comments = self.pop_comments(expr.start_byte_index());
|
||||
|
||||
let document = match expr {
|
||||
UntypedExpr::ByteArray { bytes, .. } => self.bytearray(bytes),
|
||||
UntypedExpr::ByteArray {
|
||||
bytes,
|
||||
preferred_format,
|
||||
..
|
||||
} => self.bytearray(bytes, preferred_format),
|
||||
|
||||
UntypedExpr::If {
|
||||
branches,
|
||||
|
|
|
@ -7,7 +7,10 @@ pub mod lexer;
|
|||
pub mod token;
|
||||
|
||||
use crate::{
|
||||
ast::{self, BinOp, Span, TraceKind, UnOp, UntypedDefinition, CAPTURE_VARIABLE},
|
||||
ast::{
|
||||
self, BinOp, ByteArrayFormatPreference, Span, TraceKind, UnOp, UntypedDefinition,
|
||||
CAPTURE_VARIABLE,
|
||||
},
|
||||
expr,
|
||||
};
|
||||
|
||||
|
@ -402,9 +405,12 @@ fn constant_value_parser() -> impl Parser<Token, ast::Constant, Error = ParseErr
|
|||
});
|
||||
|
||||
let constant_bytearray_parser =
|
||||
bytearray_parser().map_with_span(|bytes, span| ast::Constant::ByteArray {
|
||||
bytearray_parser().map_with_span(|(preferred_format, bytes), span| {
|
||||
ast::Constant::ByteArray {
|
||||
location: span,
|
||||
bytes,
|
||||
preferred_format,
|
||||
}
|
||||
});
|
||||
|
||||
choice((
|
||||
|
@ -414,8 +420,10 @@ fn constant_value_parser() -> impl Parser<Token, ast::Constant, Error = ParseErr
|
|||
))
|
||||
}
|
||||
|
||||
pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
||||
let bytearray_list_parser = just(Token::Hash).ignore_then(
|
||||
pub fn bytearray_parser(
|
||||
) -> impl Parser<Token, (ByteArrayFormatPreference, Vec<u8>), Error = ParseError> {
|
||||
let bytearray_list_parser = just(Token::Hash)
|
||||
.ignore_then(
|
||||
select! {Token::Int {value} => value}
|
||||
.validate(|value, span, emit| {
|
||||
let byte: u8 = match value.parse() {
|
||||
|
@ -436,10 +444,12 @@ pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
|||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare)),
|
||||
);
|
||||
)
|
||||
.map(|token| (ByteArrayFormatPreference::ArrayOfBytes, token));
|
||||
|
||||
let bytearray_hexstring_parser =
|
||||
just(Token::Hash).ignore_then(select! {Token::String {value} => value}.validate(
|
||||
let bytearray_hexstring_parser = just(Token::Hash)
|
||||
.ignore_then(
|
||||
select! {Token::String {value} => value}.validate(
|
||||
|value, span, emit| match hex::decode(value) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(_) => {
|
||||
|
@ -447,7 +457,9 @@ pub fn bytearray_parser() -> impl Parser<Token, Vec<u8>, Error = ParseError> {
|
|||
vec![]
|
||||
}
|
||||
},
|
||||
));
|
||||
),
|
||||
)
|
||||
.map(|token| (ByteArrayFormatPreference::HexadecimalString, token));
|
||||
|
||||
choice((bytearray_list_parser, bytearray_hexstring_parser))
|
||||
}
|
||||
|
@ -816,10 +828,12 @@ pub fn expr_parser(
|
|||
elems,
|
||||
});
|
||||
|
||||
let bytearray =
|
||||
bytearray_parser().map_with_span(|bytes, span| expr::UntypedExpr::ByteArray {
|
||||
let bytearray = bytearray_parser().map_with_span(|(preferred_format, bytes), span| {
|
||||
expr::UntypedExpr::ByteArray {
|
||||
location: span,
|
||||
bytes,
|
||||
preferred_format,
|
||||
}
|
||||
});
|
||||
|
||||
let list_parser = just(Token::LeftSquare)
|
||||
|
|
|
@ -311,22 +311,6 @@ fn test_block_logical_expr() {
|
|||
assert_fmt(src, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_bytearray_literals() {
|
||||
let src = indoc! {r#"
|
||||
const foo = #"ff00"
|
||||
const bar = #[0, 255]
|
||||
"#};
|
||||
|
||||
let expected = indoc! { r#"
|
||||
const foo = #"ff00"
|
||||
|
||||
const bar = #"00ff"
|
||||
"#};
|
||||
|
||||
assert_fmt(src, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_function_calls() {
|
||||
let src = indoc! {r#"
|
||||
|
@ -503,3 +487,20 @@ fn test_newline_module_comments() {
|
|||
|
||||
assert_fmt(src, out);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytearray_literals() {
|
||||
let src = indoc! {r#"
|
||||
const foo_const_array = #[102, 111, 111]
|
||||
|
||||
const foo_const_hex = #"666f6f"
|
||||
|
||||
fn foo() {
|
||||
let foo_const_array = #[102, 111, 111]
|
||||
|
||||
let foo_const_hex = #"666f6f"
|
||||
}
|
||||
"#};
|
||||
|
||||
assert_fmt(src, src);
|
||||
}
|
||||
|
|
|
@ -1785,6 +1785,7 @@ fn plain_bytearray_literals() {
|
|||
value: Box::new(Constant::ByteArray {
|
||||
location: Span::new((), 25..39),
|
||||
bytes: vec![0, 170, 255],
|
||||
preferred_format: ast::ByteArrayFormatPreference::ArrayOfBytes,
|
||||
}),
|
||||
tipo: (),
|
||||
})],
|
||||
|
@ -1813,6 +1814,7 @@ fn base16_bytearray_literals() {
|
|||
value: Box::new(Constant::ByteArray {
|
||||
location: Span::new((), 25..34),
|
||||
bytes: vec![0, 170, 255],
|
||||
preferred_format: ast::ByteArrayFormatPreference::HexadecimalString,
|
||||
}),
|
||||
tipo: (),
|
||||
}),
|
||||
|
@ -1828,6 +1830,7 @@ fn base16_bytearray_literals() {
|
|||
right: Box::new(expr::UntypedExpr::ByteArray {
|
||||
location: Span::new((), 71..80),
|
||||
bytes: vec![0, 170, 255],
|
||||
preferred_format: ast::ByteArrayFormatPreference::HexadecimalString,
|
||||
}),
|
||||
},
|
||||
doc: None,
|
||||
|
|
|
@ -350,9 +350,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
..
|
||||
} => self.infer_tuple_index(*tuple, index, location),
|
||||
|
||||
UntypedExpr::ByteArray { location, bytes } => {
|
||||
Ok(self.infer_byte_array(bytes, location))
|
||||
}
|
||||
UntypedExpr::ByteArray {
|
||||
location, bytes, ..
|
||||
} => Ok(self.infer_byte_array(bytes, location)),
|
||||
|
||||
UntypedExpr::RecordUpdate {
|
||||
location,
|
||||
|
@ -1353,7 +1353,15 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location, value, ..
|
||||
} => Ok(Constant::String { location, value }),
|
||||
|
||||
Constant::ByteArray { location, bytes } => Ok(Constant::ByteArray { location, bytes }),
|
||||
Constant::ByteArray {
|
||||
location,
|
||||
bytes,
|
||||
preferred_format,
|
||||
} => Ok(Constant::ByteArray {
|
||||
location,
|
||||
bytes,
|
||||
preferred_format,
|
||||
}),
|
||||
}?;
|
||||
|
||||
// Check type annotation is accurate.
|
||||
|
|
Loading…
Reference in New Issue