|
1 | 1 | # json5-kotlin |
2 | 2 | JSON5 implementation for Kotlin/JVM |
3 | 3 |
|
4 | | -> [!WARNING] |
5 | | -> This is an experimental project. It's non-functional at the moment. |
| 4 | +A robust JSON5 parser and serializer for Kotlin that extends JSON with helpful features like comments, trailing commas, and unquoted keys while maintaining full backward compatibility with JSON. |
6 | 5 |
|
7 | | -This project uses [Gradle](https://gradle.org/). |
8 | | -To build and run the application, use the *Gradle* tool window by clicking the Gradle icon in the right-hand toolbar, |
9 | | -or run it directly from the terminal: |
| 6 | +## Features |
10 | 7 |
|
11 | | -* Run `./gradlew run` to build and run the application. |
12 | | -* Run `./gradlew build` to only build the application. |
13 | | -* Run `./gradlew check` to run all checks, including tests. |
14 | | -* Run `./gradlew clean` to clean all build outputs. |
| 8 | +JSON5 extends JSON with the following features: |
15 | 9 |
|
16 | | -Note the usage of the Gradle Wrapper (`./gradlew`). |
17 | | -This is the suggested way to use Gradle in production projects. |
| 10 | +- **Comments**: `// line comments` and `/* block comments */` |
| 11 | +- **Trailing commas**: In objects and arrays |
| 12 | +- **Unquoted keys**: Object keys can be unquoted if they're valid identifiers |
| 13 | +- **Single quotes**: Strings can use single quotes |
| 14 | +- **Multi-line strings**: Strings can span multiple lines with `\` at line end |
| 15 | +- **Numbers**: Hexadecimal numbers, leading/trailing decimal points, explicit positive signs, infinity, and NaN |
| 16 | +- **Backward compatible**: All valid JSON is valid JSON5 |
18 | 17 |
|
19 | | -[Learn more about the Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html). |
| 18 | +## Installation |
20 | 19 |
|
21 | | -[Learn more about Gradle tasks](https://docs.gradle.org/current/userguide/command_line_interface.html#common_tasks). |
| 20 | +Add the dependency to your `build.gradle.kts`: |
22 | 21 |
|
23 | | -This project follows the suggested multi-module setup and consists of the `app` and `utils` subprojects. |
24 | | -The shared build logic was extracted to a convention plugin located in `buildSrc`. |
| 22 | +```kotlin |
| 23 | +dependencies { |
| 24 | + implementation("io.github.json5:json5-kotlin:VERSION") |
| 25 | +} |
| 26 | +``` |
25 | 27 |
|
26 | | -This project uses a version catalog (see `gradle/libs.versions.toml`) to declare and version dependencies |
27 | | -and both a build cache and a configuration cache (see `gradle.properties`). |
| 28 | +## Usage |
| 29 | + |
| 30 | +### Basic Parsing and Stringifying |
| 31 | + |
| 32 | +```kotlin |
| 33 | +import io.github.json5.kotlin.JSON5 |
| 34 | + |
| 35 | +// Parse JSON5 to Kotlin objects |
| 36 | +val json5 = """ |
| 37 | +{ |
| 38 | + // Configuration for my app |
| 39 | + name: 'MyApp', |
| 40 | + version: 2, |
| 41 | + features: ['auth', 'analytics',], // trailing comma |
| 42 | +} |
| 43 | +""" |
| 44 | + |
| 45 | +val parsed = JSON5.parse(json5) |
| 46 | +// Returns: Map<String, Any?> |
| 47 | + |
| 48 | +// Stringify Kotlin objects to JSON5 |
| 49 | +val data = mapOf( |
| 50 | + "name" to "MyApp", |
| 51 | + "version" to 2, |
| 52 | + "enabled" to true |
| 53 | +) |
| 54 | +val json5String = JSON5.stringify(data) |
| 55 | +// Returns: {name:'MyApp',version:2,enabled:true} |
| 56 | +``` |
| 57 | + |
| 58 | +### Integration with kotlinx.serialization |
| 59 | + |
| 60 | +```kotlin |
| 61 | +import io.github.json5.kotlin.JSON5 |
| 62 | +import kotlinx.serialization.Serializable |
| 63 | + |
| 64 | +@Serializable |
| 65 | +data class Config( |
| 66 | + val appName: String, |
| 67 | + val version: Int, |
| 68 | + val features: List<String>, |
| 69 | + val settings: Map<String, String> |
| 70 | +) |
| 71 | + |
| 72 | +// Serialize to JSON5 |
| 73 | +val config = Config( |
| 74 | + appName = "MyApp", |
| 75 | + version = 2, |
| 76 | + features = listOf("auth", "analytics"), |
| 77 | + settings = mapOf("theme" to "dark", "lang" to "en") |
| 78 | +) |
| 79 | + |
| 80 | +val json5 = JSON5.encodeToString(Config.serializer(), config) |
| 81 | +// Result: {appName:'MyApp',version:2,features:['auth','analytics'],settings:{theme:'dark',lang:'en'}} |
| 82 | + |
| 83 | +// Deserialize from JSON5 (with comments and formatting) |
| 84 | +val json5WithComments = """ |
| 85 | +{ |
| 86 | + // Application configuration |
| 87 | + appName: 'MyApp', |
| 88 | + version: 2, // current version |
| 89 | + features: [ |
| 90 | + 'auth', |
| 91 | + 'analytics', // trailing comma OK |
| 92 | + ], |
| 93 | + settings: { |
| 94 | + theme: 'dark', |
| 95 | + lang: 'en', |
| 96 | + } |
| 97 | +} |
| 98 | +""" |
| 99 | + |
| 100 | +val decoded = JSON5.decodeFromString(Config.serializer(), json5WithComments) |
| 101 | +// Returns: Config instance |
| 102 | +``` |
| 103 | + |
| 104 | +### Advanced Features |
| 105 | + |
| 106 | +```kotlin |
| 107 | +// JSON5 supports various number formats |
| 108 | +val numbers = JSON5.parse(""" |
| 109 | +{ |
| 110 | + hex: 0xDECAF, |
| 111 | + leadingDot: .8675309, |
| 112 | + trailingDot: 8675309., |
| 113 | + positiveSign: +1, |
| 114 | + scientific: 6.02e23, |
| 115 | + infinity: Infinity, |
| 116 | + negativeInfinity: -Infinity, |
| 117 | + notANumber: NaN |
| 118 | +} |
| 119 | +""") |
| 120 | + |
| 121 | +// Multi-line strings and comments |
| 122 | +val complex = JSON5.parse(""" |
| 123 | +{ |
| 124 | + multiLine: "This is a \ |
| 125 | +multi-line string", |
| 126 | + /* Block comment |
| 127 | + spanning multiple lines */ |
| 128 | + singleQuoted: 'Can contain "double quotes"', |
| 129 | + unquoted: 'keys work too' |
| 130 | +} |
| 131 | +""") |
| 132 | +``` |
| 133 | + |
| 134 | +## Building the Project |
| 135 | + |
| 136 | +This project uses [Gradle](https://gradle.org/) with Java 21: |
| 137 | + |
| 138 | +```bash |
| 139 | +./gradlew build # Build the library |
| 140 | +./gradlew test # Run tests |
| 141 | +./gradlew check # Run all checks including tests |
| 142 | +``` |
| 143 | + |
| 144 | +## License |
| 145 | + |
| 146 | +This project is licensed under the terms specified in the [LICENSE](LICENSE) file. |
0 commit comments