or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/maven-io-circe--circe-core

Core module of circe, a JSON library for Scala that enables developers to encode and decode JSON data with type safety and functional programming principles.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.circe/circe-core_2.13@0.14.x

To install, run

npx @tessl/cli install tessl/maven-io-circe--circe-core@0.14.0

0

# Circe Core

1

2

Circe is a comprehensive JSON library for Scala that enables developers to encode and decode JSON data with type safety and functional programming principles. The core module contains fundamental data types like Json, JsonObject, JsonNumber, and essential type classes including Encoder, Decoder, and Codec for converting between Scala values and JSON. It offers a cursor-based API for navigating and manipulating JSON structures, comprehensive error handling with detailed failure information, and seamless integration with the Cats functional programming ecosystem.

3

4

## Package Information

5

6

- **Package Name**: io.circe:circe-core_2.13

7

- **Package Type**: maven

8

- **Language**: Scala

9

- **Installation**: `libraryDependencies += "io.circe" %% "circe-core" % "0.14.13"`

10

11

## Core Imports

12

13

```scala

14

import io.circe._

15

import io.circe.syntax._

16

```

17

18

Import specific components:

19

20

```scala

21

import io.circe.{Json, JsonObject, JsonNumber, Encoder, Decoder, Codec}

22

import io.circe.{HCursor, ACursor, DecodingFailure, ParsingFailure}

23

import io.circe.{Printer, KeyEncoder, KeyDecoder}

24

```

25

26

## Basic Usage

27

28

### JSON Construction

29

30

```scala

31

import io.circe._

32

import io.circe.syntax._

33

34

// Direct JSON construction using factory methods

35

val json = Json.obj(

36

"name" -> Json.fromString("John"),

37

"age" -> Json.fromInt(30),

38

"active" -> Json.fromBoolean(true),

39

"scores" -> Json.arr(Json.fromInt(85), Json.fromInt(92), Json.fromInt(78))

40

)

41

42

// Using constants and collection builders

43

val nullValue = Json.Null

44

val trueValue = Json.True

45

val falseValue = Json.False

46

val arrayJson = Json.fromValues(List(Json.fromInt(1), Json.fromInt(2), Json.fromInt(3)))

47

val objectJson = Json.fromFields(List("key1" -> Json.fromString("value1"), "key2" -> Json.fromInt(42)))

48

```

49

50

### Encoding to JSON

51

52

```scala

53

import io.circe._

54

import io.circe.syntax._

55

56

// Basic encoding with syntax extension

57

val name = "John"

58

val age = 30

59

val active = true

60

61

val nameJson = name.asJson // Json

62

val ageJson = age.asJson // Json

63

val activeJson = active.asJson // Json

64

65

// Object encoding with key syntax operator

66

val personJson = Json.obj(

67

"name" := "John",

68

"age" := 30,

69

"active" := true

70

)

71

72

// Type class based encoding

73

case class Person(name: String, age: Int, active: Boolean)

74

implicit val personEncoder: Encoder[Person] = Encoder.forProduct3("name", "age", "active")(p => (p.name, p.age, p.active))

75

76

val person = Person("John", 30, true)

77

val encoded = person.asJson // Json

78

```

79

80

### Decoding from JSON

81

82

```scala

83

import io.circe._

84

import io.circe.parser._

85

86

// Basic decoding

87

val json = parse("""{"name":"John","age":30,"active":true}""").getOrElse(Json.Null)

88

89

val cursor = json.hcursor

90

val name: Decoder.Result[String] = cursor.downField("name").as[String]

91

val age: Decoder.Result[Int] = cursor.downField("age").as[Int]

92

93

// Object decoding

94

implicit val personDecoder: Decoder[Person] = Decoder.forProduct3("name", "age", "active")(Person.apply)

95

96

val person: Either[DecodingFailure, Person] = json.as[Person]

97

```

98

99

### Cursor Navigation

100

101

```scala

102

import io.circe._

103

import io.circe.parser._

104

105

val jsonString = """{"users":[{"name":"John","age":30},{"name":"Jane","age":25}]}"""

106

val json = parse(jsonString).getOrElse(Json.Null)

107

108

val cursor = json.hcursor

109

val firstUserName = cursor

110

.downField("users")

111

.downArray

112

.downField("name")

113

.as[String] // Right("John")

114

```

115

116

### JSON Manipulation

117

118

```scala

119

import io.circe._

120

121

val json1 = Json.obj("name" := "John", "age" := 30)

122

val json2 = Json.obj("age" := 31, "city" := "NYC")

123

124

// Deep merge JSON objects

125

val merged = json1.deepMerge(json2) // {"name":"John","age":31,"city":"NYC"}

126

127

// Remove null values

128

val withNulls = Json.obj("name" := "John", "email" := Json.Null, "age" := 30)

129

val cleaned = withNulls.dropNullValues // {"name":"John","age":30}

130

131

// Search for keys

132

val nested = Json.obj("user" := Json.obj("profile" := Json.obj("name" := "John")))

133

val names = nested.findAllByKey("name") // List(Json.fromString("John"))

134

val namesAlt = nested \\ "name" // Alternative syntax

135

```

136

137

### JSON Printing

138

139

```scala

140

import io.circe._

141

142

val json = Json.obj("name" := "John", "age" := 30, "scores" := Json.arr(85, 92, 78))

143

144

// Built-in printing options

145

val compact = json.noSpaces // {"name":"John","age":30,"scores":[85,92,78]}

146

val pretty = json.spaces2 // Pretty printed with 2-space indentation

147

val sorted = json.spaces2SortKeys // Pretty printed with sorted keys

148

149

// Custom printer

150

val printer = Printer.noSpaces.copy(dropNullValues = true, sortKeys = true)

151

val custom = printer.print(json)

152

```

153

154

## Architecture

155

156

Circe-core is built around several key abstractions:

157

158

- **Json**: Immutable representation of JSON values with a rich API for manipulation

159

- **Type Classes**: Encoder/Decoder pattern for type-safe conversion between Scala and JSON

160

- **Cursors**: Zipper-like navigation API for traversing and modifying JSON structures

161

- **Error Handling**: Comprehensive failure types with detailed path information

162

- **Printing**: Configurable JSON formatting and output

163

164

## Capabilities

165

166

### JSON Data Types

167

168

Core data structures for representing JSON values with factory methods and manipulation APIs.

169

170

```scala { .api }

171

sealed abstract class Json {

172

// Type checking

173

def isNull: Boolean

174

def isBoolean: Boolean

175

def isNumber: Boolean

176

def isString: Boolean

177

def isArray: Boolean

178

def isObject: Boolean

179

180

// Pattern matching

181

def fold[X](

182

jsonNull: => X,

183

jsonBoolean: Boolean => X,

184

jsonNumber: JsonNumber => X,

185

jsonString: String => X,

186

jsonArray: Vector[Json] => X,

187

jsonObject: JsonObject => X

188

): X

189

190

// Manipulation

191

def deepMerge(that: Json): Json

192

def dropNullValues: Json

193

def dropEmptyValues: Json

194

def findAllByKey(key: String): List[Json]

195

def \\(key: String): List[Json]

196

197

// Printing

198

def noSpaces: String

199

def spaces2: String

200

def spaces4: String

201

def spaces2SortKeys: String

202

def printWith(printer: Printer): String

203

}

204

205

object Json {

206

// Constants

207

val Null: Json

208

val True: Json

209

val False: Json

210

211

// Factory methods

212

def obj(fields: (String, Json)*): Json

213

def arr(values: Json*): Json

214

def fromFields(fields: Iterable[(String, Json)]): Json

215

def fromValues(values: Iterable[Json]): Json

216

def fromString(value: String): Json

217

def fromBoolean(value: Boolean): Json

218

def fromInt(value: Int): Json

219

def fromLong(value: Long): Json

220

def fromDouble(value: Double): Json

221

def fromBigDecimal(value: BigDecimal): Json

222

}

223

224

final case class JsonObject {

225

def apply(key: String): Option[Json]

226

def contains(key: String): Boolean

227

def size: Int

228

def isEmpty: Boolean

229

def keys: Iterable[String]

230

def values: Iterable[Json]

231

def add(key: String, value: Json): JsonObject

232

def remove(key: String): JsonObject

233

def mapValues(f: Json => Json): JsonObject

234

def deepMerge(that: JsonObject): JsonObject

235

}

236

237

sealed abstract class JsonNumber {

238

def toBigDecimal: Option[BigDecimal]

239

def toBigInt: Option[BigInt]

240

def toDouble: Double

241

def toLong: Option[Long]

242

def toInt: Option[Int]

243

}

244

```

245

246

[JSON Data Types](./json-data-types.md)

247

248

### Type Classes

249

250

Type-safe encoding and decoding between Scala types and JSON with combinators and instances.

251

252

```scala { .api }

253

trait Encoder[A] {

254

def apply(a: A): Json

255

def contramap[B](f: B => A): Encoder[B]

256

def mapJson(f: Json => Json): Encoder[A]

257

}

258

259

object Encoder {

260

def apply[A](implicit instance: Encoder[A]): Encoder[A]

261

def instance[A](f: A => Json): Encoder[A]

262

263

// Primitive instances

264

implicit val encodeString: Encoder[String]

265

implicit val encodeInt: Encoder[Int]

266

implicit val encodeBoolean: Encoder[Boolean]

267

implicit val encodeDouble: Encoder[Double]

268

implicit val encodeBigDecimal: Encoder[BigDecimal]

269

270

// Collection instances

271

implicit def encodeList[A: Encoder]: Encoder[List[A]]

272

implicit def encodeVector[A: Encoder]: Encoder[Vector[A]]

273

implicit def encodeSet[A: Encoder]: Encoder[Set[A]]

274

implicit def encodeMap[A: Encoder]: Encoder[Map[String, A]]

275

implicit def encodeOption[A: Encoder]: Encoder[Option[A]]

276

277

// Subtypes

278

trait AsObject[A] extends Encoder[A] {

279

def encodeObject(a: A): JsonObject

280

}

281

282

trait AsArray[A] extends Encoder[A] {

283

def encodeArray(a: A): Vector[Json]

284

}

285

}

286

287

trait Decoder[A] {

288

def apply(c: HCursor): Decoder.Result[A]

289

def map[B](f: A => B): Decoder[B]

290

def flatMap[B](f: A => Decoder[B]): Decoder[B]

291

def emap[B](f: A => Either[String, B]): Decoder[B]

292

def ensure(pred: A => Boolean, message: => String): Decoder[A]

293

def at(field: String): Decoder[A]

294

def prepare(f: ACursor => ACursor): Decoder[A]

295

}

296

297

object Decoder {

298

type Result[A] = Either[DecodingFailure, A]

299

type AccumulatingResult[A] = ValidatedNel[DecodingFailure, A]

300

301

def apply[A](implicit instance: Decoder[A]): Decoder[A]

302

def instance[A](f: HCursor => Result[A]): Decoder[A]

303

def const[A](a: A): Decoder[A]

304

def failed[A](failure: DecodingFailure): Decoder[A]

305

306

// Primitive instances

307

implicit val decodeString: Decoder[String]

308

implicit val decodeInt: Decoder[Int]

309

implicit val decodeBoolean: Decoder[Boolean]

310

implicit val decodeDouble: Decoder[Double]

311

implicit val decodeBigDecimal: Decoder[BigDecimal]

312

313

// Collection instances (similar to Encoder)

314

implicit def decodeList[A: Decoder]: Decoder[List[A]]

315

implicit def decodeVector[A: Decoder]: Decoder[Vector[A]]

316

implicit def decodeOption[A: Decoder]: Decoder[Option[A]]

317

implicit def decodeMap[A: Decoder]: Decoder[Map[String, A]]

318

}

319

320

trait Codec[A] extends Decoder[A] with Encoder[A] {

321

def iemap[B](f: A => Either[String, B])(g: B => A): Codec[B]

322

}

323

324

object Codec {

325

def from[A](decoder: Decoder[A], encoder: Encoder[A]): Codec[A]

326

}

327

```

328

329

[Type Classes](./type-classes.md)

330

331

### Cursor Navigation

332

333

Zipper-like API for navigating and manipulating JSON structures with path tracking.

334

335

```scala { .api }

336

abstract class ACursor {

337

def focus: Option[Json]

338

def succeeded: Boolean

339

def failed: Boolean

340

def history: List[CursorOp]

341

342

// Navigation

343

def top: Option[Json]

344

def up: ACursor

345

def left: ACursor

346

def right: ACursor

347

def downField(k: String): ACursor

348

def downArray: ACursor

349

def downN(n: Int): ACursor

350

def field(k: String): ACursor

351

352

// Modification

353

def withFocus(f: Json => Json): ACursor

354

def set(j: Json): ACursor

355

def delete: ACursor

356

357

// Decoding

358

def as[A](implicit d: Decoder[A]): Decoder.Result[A]

359

def get[A](k: String)(implicit d: Decoder[A]): Decoder.Result[A]

360

def getOrElse[A](k: String)(fallback: => A)(implicit d: Decoder[A]): A

361

}

362

363

abstract class HCursor extends ACursor {

364

def value: Json

365

def root: HCursor

366

def keys: Option[Iterable[String]]

367

def values: Option[Iterable[Json]]

368

}

369

370

object HCursor {

371

def fromJson(value: Json): HCursor

372

}

373

374

sealed abstract class CursorOp {

375

def requiresArray: Boolean

376

def requiresObject: Boolean

377

}

378

379

object CursorOp {

380

case object MoveLeft extends CursorOp

381

case object MoveRight extends CursorOp

382

case object MoveUp extends CursorOp

383

case object DownArray extends CursorOp

384

case class DownField(k: String) extends CursorOp

385

case class DownN(n: Int) extends CursorOp

386

case class Field(k: String) extends CursorOp

387

}

388

```

389

390

[Cursor Navigation](./cursor-navigation.md)

391

392

### Error Handling

393

394

Comprehensive error types with detailed failure information and path tracking.

395

396

```scala { .api }

397

sealed abstract class Error extends Exception

398

399

final case class ParsingFailure(

400

message: String,

401

underlying: Throwable

402

) extends Error

403

404

sealed abstract class DecodingFailure extends Error {

405

def message: String

406

def history: List[CursorOp]

407

def pathToRootString: Option[String]

408

def reason: DecodingFailure.Reason

409

410

def withMessage(message: String): DecodingFailure

411

def withReason(reason: DecodingFailure.Reason): DecodingFailure

412

}

413

414

object DecodingFailure {

415

sealed abstract class Reason

416

417

object Reason {

418

case object MissingField extends Reason

419

case class WrongTypeExpectation(expected: String, got: Json) extends Reason

420

case class CustomReason(message: String) extends Reason

421

}

422

423

def apply(message: String, ops: List[CursorOp]): DecodingFailure

424

def apply(message: String, cursor: ACursor): DecodingFailure

425

}

426

427

final case class Errors(errors: NonEmptyList[Error]) extends Exception

428

```

429

430

[Error Handling](./error-handling.md)

431

432

### Key Encoding and Decoding

433

434

Type-safe conversion of object keys between Scala types and strings.

435

436

```scala { .api }

437

trait KeyEncoder[A] {

438

def apply(key: A): String

439

}

440

441

trait KeyDecoder[A] {

442

def apply(key: String): Option[A]

443

}

444

```

445

446

[Key Encoding and Decoding](./key-encoding-decoding.md)

447

448

### JSON Printing

449

450

Configurable JSON formatting and output with extensive customization options.

451

452

```scala { .api }

453

final case class Printer(

454

dropNullValues: Boolean,

455

indent: String,

456

lbraceLeft: String,

457

lbraceRight: String,

458

rbraceLeft: String,

459

rbraceRight: String,

460

lbracketLeft: String,

461

lbracketRight: String,

462

rbracketLeft: String,

463

rbracketRight: String,

464

lrbracketsEmpty: String,

465

arrayCommaLeft: String,

466

arrayCommaRight: String,

467

objectCommaLeft: String,

468

objectCommaRight: String,

469

colonLeft: String,

470

colonRight: String,

471

escapeNonAscii: Boolean,

472

sortKeys: Boolean,

473

reuseWriters: Boolean,

474

predictSize: Boolean

475

) {

476

def print(json: Json): String

477

def printToByteBuffer(json: Json): ByteBuffer

478

def withSortedKeys: Printer

479

}

480

481

object Printer {

482

val noSpaces: Printer

483

val spaces2: Printer

484

val spaces4: Printer

485

val noSpacesSortKeys: Printer

486

val spaces2SortKeys: Printer

487

val spaces4SortKeys: Printer

488

489

def indented(indent: String, sortKeys: Boolean = false): Printer

490

}

491

```

492

493

[JSON Printing](./json-printing.md)

494

495

## Types

496

497

### Core Result Types

498

499

```scala { .api }

500

object Decoder {

501

type Result[A] = Either[DecodingFailure, A]

502

type AccumulatingResult[A] = ValidatedNel[DecodingFailure, A]

503

}

504

505

sealed abstract class CursorOp

506

```

507

508

### Extension Types

509

510

```scala { .api }

511

// Syntax extensions for encoding

512

implicit class EncoderOps[A](private val value: A) extends AnyVal {

513

def asJson(implicit encoder: Encoder[A]): Json

514

def asJsonObject(implicit encoder: Encoder.AsObject[A]): JsonObject

515

}

516

517

// Syntax extensions for object key creation

518

implicit class KeyOps[K](private val value: K) extends AnyVal {

519

def :=[A: Encoder](a: A)(implicit keyEncoder: KeyEncoder[K]): (String, Json)

520

}

521

522

// Syntax extensions for JSON values

523

implicit class JsonOps(private val json: Json) extends AnyVal {

524

def hcursor: HCursor

525

def as[A](implicit decoder: Decoder[A]): Decoder.Result[A]

526

def asAccumulating[A](implicit decoder: Decoder[A]): Decoder.AccumulatingResult[A]

527

def \\(key: String): List[Json]

528

def findAllByKey(key: String): List[Json]

529

}

530

531

// Syntax extensions for cursors

532

implicit class ACursorOps(private val cursor: ACursor) extends AnyVal {

533

def as[A](implicit decoder: Decoder[A]): Decoder.Result[A]

534

def get[A](key: String)(implicit decoder: Decoder[A]): Decoder.Result[A]

535

def getOrElse[A](key: String)(fallback: => A)(implicit decoder: Decoder[A]): A

536

}

537

```