Code Monkey home page Code Monkey logo

tomlkit's Introduction

TOMLKit

A small, simple TOML parser and serializer for Swift. Powered by toml++.

Swift 5.4 SPM Compatible Build and Test

TOMLKit is a Swift wrapper around toml++, allowing you to parse and serialize TOML files in Swift.

Table of Contents

Created by gh-md-toc

Installation

Swift Package Manager

Add this to the dependencies array in Package.swift:

.package(url: "https://github.com/LebJe/TOMLKit.git", from: "0.5.0")

Also add this to the targets array in the aforementioned file:

.product(name: "TOMLKit", package: "TOMLKit")

Quick Start

import TOMLKit
import struct Foundation.Date

let toml = """
string = "Hello, World!"
int = 523053
double = 3250.34
"""

struct Test: Codable {
    let string: String
    let int: Int
    let double: Double
}

do {
   let table = try TOMLTable(string: toml)
   table.remove(at: "double")

   table["dateTime"] = TOMLDateTime(date: Foundation.Date())
   table.insert(
      TOMLArray([1, 2, "3", TOMLTable(["time": TOMLTime(hour: 10, minute: 26, second: 49, nanoSecond: 203)])]),
      at: "array"
   )

   let test = Test(string: "Goodbye, World!", int: 24598, double: 18.247)
   let encodedTest: TOMLTable = try TOMLEncoder().encode(test)
   let decodedTest = try TOMLDecoder().decode(Test.self, from: encodedTest)

   print("----Encoding & Decoding----\n")

   print("Encoded Test: \n\(encodedTest)\n")
   print("Decoded Test: \(decodedTest)")

   print("\n----Conversion----\n")

   print("TOML:\n\(table.convert(to: .toml))\n")
   print("JSON:\n\(table.convert(to: .json))\n")
   print("YAML:\n\(table.convert(to: .yaml))")
} catch let error as TOMLParseError {
   // TOMLParseError occurs when the TOML document is invalid.
   // `error.source.begin` contains the line and column where the error started,
   // and `error.source.end` contains the line where the error ended.
    print(error.source.begin)
    print(error.source.end)
}

// ----Encoding & Decoding----
//
// Encoded Test:
// double = 18.247
// int = 24598
// string = 'Goodbye, World!'
//
// Decoded Test: Test(string: "Goodbye, World!", int: 24598, double: 18.247)
//
// ----Conversion----
//
// TOML:
// array = [ 1, 2, '3', { time = 10:26:49.000000203 } ]
// dateTime = 2022-03-31T12:19:38.160653948Z
// int = 523053
// string = 'Hello, World!'
//
// JSON:
// {
//     "array" : [
//         1,
//         2,
//         "3",
//         {
//             "time" : "10:26:49.000000203"
//         }
//     ],
//     "dateTime" : "2022-03-31T12:19:38.160653948Z",
//     "int" : 523053,
//     "string" : "Hello, World!"
// }
//
// YAML:
// array:
//   - 1
//   - 2
//   - 3
//   - time: '10:26:49.000000203'
// dateTime: '2022-03-31T12:19:38.160653948Z'
// int: 523053
// string: 'Hello, World!'

Full Documentation

Full documentation is available here.

Dependencies

Licenses

The toml++ license is available in the tomlplusplus directory in the LICENSE file.

Contributing

Before committing, please install pre-commit, swift-format, clang-format, and Prettier, then install the pre-commit hook:

$ brew bundle # install the packages specified in Brewfile
$ pre-commit install

# Commit your changes.

To install pre-commit on other platforms, refer to the documentation.

tomlkit's People

Contributors

furby-tm avatar lebje avatar stackotter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

tomlkit's Issues

Memory Leaks on iOS `TOMLTable.convert(to:options:)`

My Code is quit simple:

// a toml string
var tomlString = '''
port = 6789
socks_port = 7890
allow_lan = false
bind_address = '*'
log_level = 'debug'
ipv6 = false
tun_fd = 0
'''
// `NetspeedConfig` is a Swift Struct define in my app
var config = try TOMLDecoder().decode(NetspeedConfig.self, from: tomlString)

// set property etc.
config.tun_fd = 10
...

// convert to toml string
tomlString = try TOMLEncoder().encode(config)

// create a TOMLKit table
let table = try TOMLTable(string: tomlString)

// convert to strings
let output_toml = table.convert(to: .toml)
let output_json = table.convert(to: .json)
let output_yaml = table.convert(to: .yaml)
iShot_2024-01-09_16 46 58

Xcode Instruments catch this memory leak, please download it and check in Xcode
https://github.com/codingiran/TOMLKit/blob/main/MemoryLeaks/TOMlKit%20Memory%20Leaks.trace.zip

SwiftPM takes a long time to resolve TOMLKit

Hi Jeff,

In both of my packages that use TOMLKit, it always takes a lot longer for SwiftPM and Xcode to resolve TOMLKit than any of the other dependencies. I was going to attach a screenshot of the log from resolving dependencies after clearing the cache, but Xcode crashed before I could take the screenshot. However, I did see that all other dependencies were resolved in under 5 seconds, and TOMLKit took 138 seconds to resolve.

I ran swift package resolve -v and the longest step seems to be the git submodule update --init --recursive step for TOMLKit because of tomlplusplus's json submodule with over 4300 commits. The tomlplusplus submodule doesn't seem necessary for building TOMLKit, so would it be possible to remove it and instead just put the commit of tomlplusplus that TOMLKit uses in a file somewhere?

Fatal crash (may be caused by a bug in toml++)

Hi @LebJe,

I have found a reproducible fatal crash in TOMLKit. Here's the minimum code that I have been able to reproduce the crash with:

import Foundation
import TOMLKit

let string = "[[apps.test]]"

struct Child: Codable {
    var value: String // if Child is an empty struct it doesn't crash
}

struct Parent: Codable {
    var apps: [String: Child] // if this is just `[String: String]` it doesn't crash
}

try? TOMLDecoder().decode(Parent.self, from: string)

The realworld use case I have that runs into this fatal crash (with incorrect TOML input) is decoding this Configuration struct from this string:

[[apps.HelloWorld]]
product = "HelloWorld"
version = "0.1.0"

The TOML is invalid because it's not meant to have double square brackets, however fatal crashes shouldn't occur even with invalid input.

I have done a bit of poking around and I think I have found the issue. TOMLKit thinks that the array at coding path apps.HelloWorld is both a table and an array (these values are from inside TOMLTable.keys):

(lldb) po tomlValue.array
▿ Optional<TOMLArray>
  ▿ some : [ { minimum_macos_version = '11', product = 'HelloWorld', version = '0.1.0' } ]

(lldb) po tomlValue.table
▿ Optional<TOMLTable>
  ▿ some : [ { minimum_macos_version = '11', product = 'HelloWorld', version = '0.1.0' } ]

For some reason casting the value to both an array and a table succeeds.

I have found a way to fix the crash: checking the type of the node before attempting to cast it so that these invalid type casts can't occur anymore.

I will submit a PR soon with the required changes (once I have run the tests).

Feature: Strict decoding

I am currently using TOMLKit in a few projects to decode configuration files. It would be extremely useful if TOMLKit's Codable implementation had an option to do strict decoding. By strict decoding I mean throwing an error if any unexpected keys are present. This makes typos of optional keys a lot easier for users to detect (because the typoed key would cause an error to be thrown instead of just silently being ignored).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.