Skip to content

Commit

Permalink
update lockfile and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bgreni committed Nov 1, 2024
1 parent a2c14c6 commit 4ac03a0
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 189 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ A lightweight JSON parsing library for Mojo.

## Usage

### Parsing from a string

```mojo
from ember_json import *
Expand Down Expand Up @@ -34,3 +36,24 @@ fn main() raises:
# `Value` type is formattable to allow for direct printing
print(json[0]) # prints 123
```

### Stringify

```mojo
# convert to string
var json = JSON.from_string('{"key": 123}')
print(str(json)) # prints '{"key":123}'
# JSON is Writable so you can also just print it directly, or
# even write you own stringify implementation!
print(json)
# pretty printing
from ember_json import write_pretty
print(write_pretty(json))
"""
{
"key": 123
}
"""
```
4 changes: 2 additions & 2 deletions ember_json/array.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ struct Array(Sized, JsonValue):
fn append(inout self, owned item: Value):
self._data.append(item^)

fn bytes_for_string(self) -> Int:
fn min_size_for_string(self) -> Int:
var n = 2
for item in self._data:
n += item[].bytes_for_string() + 1
n += item[].min_size_for_string() + 1
n -= 1

return n
Expand Down
23 changes: 18 additions & 5 deletions ember_json/json.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ from .array import Array
from .constants import *
from .traits import JsonValue, PrettyPrintable
from .utils import write, ByteView
from sys.intrinsics import unlikely


@value
Expand All @@ -30,9 +31,19 @@ struct JSON(JsonValue, Sized, PrettyPrintable):

alias Type = Variant[Object, Array]
var _data: Self.Type
var _source_len: Int

fn __init__(inout self):
self._data = Object()
self._source_len = 0

fn __init__(inout self, owned ob: Object):
self._data = ob^
self._source_len = 0

fn __init__(inout self, owned arr: Array):
self._data = arr^
self._source_len = 0

@always_inline
fn _get[T: CollectionElement](ref [_]self: Self) -> ref [self._data] T:
Expand Down Expand Up @@ -206,18 +217,20 @@ struct JSON(JsonValue, Sized, PrettyPrintable):
raise Error("Invalid json")

reader.skip_whitespace()
if reader.has_more():
if unlikely(reader.has_more()):
raise Error("Invalid json, expected end of input, recieved: " + reader.remaining())

return data
data._source_len = len(input)

return data^

fn bytes_for_string(self) -> Int:
fn min_size_for_string(self) -> Int:
"""Should only be used as an estimatation. Sizes of float values are
unreliable.
"""
if self.is_array():
return self.array().bytes_for_string()
return self.object().bytes_for_string()
return self.array().min_size_for_string()
return self.object().min_size_for_string()

@staticmethod
fn try_from_string(input: String) -> Optional[JSON]:
Expand Down
4 changes: 2 additions & 2 deletions ember_json/object.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ struct Object(Sized, JsonValue, PrettyPrintable):
fn __init__(inout self):
self._data = Self.Type()

fn bytes_for_string(self) -> Int:
fn min_size_for_string(self) -> Int:
var n = 2 + len(self) # include ':' for each pairing
for k in self._data:
try:
n += 3 + len(k[]) + self._data[k[]].bytes_for_string()
n += 3 + len(k[]) + self._data[k[]].min_size_for_string()
except:
pass
n -= 1
Expand Down
5 changes: 4 additions & 1 deletion ember_json/traits.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ trait PrettyPrintable:
fn pretty_to[W: Writer](self, inout writer: W, indent: String):
...

trait StringSize:
fn min_size_for_string(self) -> Int:
...

trait JsonValue(EqualityComparableCollectionElement, Writable, Stringable, Representable):
trait JsonValue(EqualityComparableCollectionElement, Writable, Stringable, Representable, StringSize):
pass
10 changes: 5 additions & 5 deletions ember_json/value.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct Null(JsonValue):
fn __repr__(self) -> String:
return self.__str__()

fn bytes_for_string(self) -> Int:
fn min_size_for_string(self) -> Int:
return 4

fn write_to[W: Writer](self, inout writer: W):
Expand Down Expand Up @@ -269,7 +269,7 @@ struct Value(JsonValue):
else:
self.write_to(writer)

fn bytes_for_string(self) -> Int:
fn min_size_for_string(self) -> Int:
if self.isa[Int]():
return _calc_initial_buffer_size(self.int()) - 1
elif self.isa[Float64]():
Expand All @@ -279,11 +279,11 @@ struct Value(JsonValue):
elif self.isa[Bool]():
return 4 if self.bool() else 5
elif self.isa[Null]():
return Null().bytes_for_string()
return Null().min_size_for_string()
elif self.isa[Object]():
return self.object().bytes_for_string()
return self.object().min_size_for_string()
elif self.isa[Array]():
return self.array().bytes_for_string()
return self.array().min_size_for_string()

return 0

Expand Down
Loading

0 comments on commit 4ac03a0

Please sign in to comment.