Skip to content

Improve support for empty and non-ASCII-alphabetic properties, enum values, and definitions #17

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

Merged
merged 3 commits into from
Apr 2, 2021
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
1 change: 1 addition & 0 deletions Cargo.lock

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

32 changes: 23 additions & 9 deletions crates/core/src/target/inflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,21 @@ impl Inflector for TailInflector {
fn decompose(s: &str) -> Vec<String> {
let mut out: Vec<Vec<char>> = vec![vec![]];
for c in s.chars() {
if c.is_whitespace() || c == '-' || c == '_' || c == ':' {
// Non-ASCII alphanumeric characters, such as whitespace, dashes,
// underscores, or non-ASCII characters, are presumed to always be
// delimiters.
if !c.is_ascii_alphanumeric() {
out.push(vec![]);
continue;
}

// Do not allow a part to start with a digit. Most languages prohibit
// digits at the beginning of identifiers. Just ignore the digit to make
// this happen.
if c.is_ascii_digit() && out.last().unwrap().is_empty() {
continue;
}

if let Some(last_char) = out.last().unwrap().last() {
if last_char.is_lowercase() && c.is_uppercase() {
out.push(vec![]);
Expand Down Expand Up @@ -154,13 +164,17 @@ impl Case {
}

pub fn inflect(&self, words: &[String]) -> String {
if words.is_empty() {
return "".to_owned();
let mut word_parts: Vec<_> = words.into_iter().flat_map(|word| decompose(word)).collect();

// If after decomposing the word into its parts (and after the
// associated stripping of non-ASCII alphanumerics) we don't have any
// words to work with, then inflect a "default name" instead.
if word_parts.is_empty() {
word_parts = vec!["default".into(), "name".into()];
}

let parts: Vec<_> = words
let parts: Vec<_> = word_parts
.into_iter()
.flat_map(|word| decompose(word))
.enumerate()
.map(|(i, word)| {
if self.initialisms.contains(&word) {
Expand Down Expand Up @@ -245,7 +259,7 @@ mod tests {

#[test]
fn test_camel_case() {
assert_eq!("", Case::camel_case().inflect(&[]));
assert_eq!("defaultName", Case::camel_case().inflect(&[]));

assert_eq!("foo", Case::camel_case().inflect(&["foo".to_owned()]));
assert_eq!(
Expand All @@ -260,7 +274,7 @@ mod tests {

#[test]
fn test_pascal_case() {
assert_eq!("", Case::pascal_case().inflect(&[]));
assert_eq!("DefaultName", Case::pascal_case().inflect(&[]));

assert_eq!("Foo", Case::pascal_case().inflect(&["foo".to_owned()]));
assert_eq!(
Expand All @@ -275,7 +289,7 @@ mod tests {

#[test]
fn test_snake_case() {
assert_eq!("", Case::snake_case().inflect(&[]));
assert_eq!("default_name", Case::snake_case().inflect(&[]));

assert_eq!("foo", Case::snake_case().inflect(&["foo".to_owned()]));
assert_eq!(
Expand All @@ -290,7 +304,7 @@ mod tests {

#[test]
fn test_screaming_snake_case() {
assert_eq!("", Case::screaming_snake_case().inflect(&[]));
assert_eq!("DEFAULT_NAME", Case::screaming_snake_case().inflect(&[]));

assert_eq!(
"FOO",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(DefaultNameJsonConverter))]
public class DefaultName
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class DefaultNameJsonConverter : JsonConverter<DefaultName>
{
public override DefaultName Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new DefaultName { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, DefaultName value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(FooJsonConverter))]
public class Foo
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class FooJsonConverter : JsonConverter<Foo>
{
public override Foo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new Foo { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, Foo value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(Foo0JsonConverter))]
public class Foo0
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class Foo0JsonConverter : JsonConverter<Foo0>
{
public override Foo0 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new Foo0 { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, Foo0 value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(Foo0barJsonConverter))]
public class Foo0bar
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class Foo0barJsonConverter : JsonConverter<Foo0bar>
{
public override Foo0bar Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new Foo0bar { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, Foo0bar value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(Foo1JsonConverter))]
public class Foo1
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class Foo1JsonConverter : JsonConverter<Foo1>
{
public override Foo1 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new Foo1 { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, Foo1 value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(FooBarJsonConverter))]
public class FooBar
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class FooBarJsonConverter : JsonConverter<FooBar>
{
public override FooBar Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new FooBar { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, FooBar value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(FooBar0JsonConverter))]
public class FooBar0
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class FooBar0JsonConverter : JsonConverter<FooBar0>
{
public override FooBar0 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new FooBar0 { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, FooBar0 value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(FooBar1JsonConverter))]
public class FooBar1
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class FooBar1JsonConverter : JsonConverter<FooBar1>
{
public override FooBar1 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new FooBar1 { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, FooBar1 value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Code generated by jtd-codegen for C# + System.Text.Json v0.2.0

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace JtdCodegenE2E
{
[JsonConverter(typeof(RootJsonConverter))]
public class Root
{
/// <summary>
/// The underlying data being wrapped.
/// </summary>
public string Value { get; set; }
}

public class RootJsonConverter : JsonConverter<Root>
{
public override Root Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return new Root { Value = JsonSerializer.Deserialize<string>(ref reader, options) };
}

public override void Write(Utf8JsonWriter writer, Root value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<string>(writer, value.Value, options);
}
}
}
Loading