{"id":18473416,"url":"https://github.com/0xopenbytes/flet","last_synced_at":"2025-04-08T12:31:52.012Z","repository":{"id":63901294,"uuid":"471782763","full_name":"0xOpenBytes/FLet","owner":"0xOpenBytes","description":"Micro Framework Collection","archived":false,"fork":false,"pushed_at":"2022-05-06T19:44:04.000Z","size":7,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-23T12:32:49.184Z","etag":null,"topics":["cache","composition","input","output","spm","swift","testing","transformations","transput"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0xOpenBytes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-19T18:39:20.000Z","updated_at":"2023-03-13T19:28:14.000Z","dependencies_parsed_at":"2023-01-14T12:45:25.988Z","dependency_job_id":null,"html_url":"https://github.com/0xOpenBytes/FLet","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FFLet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FFLet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FFLet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xOpenBytes%2FFLet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xOpenBytes","download_url":"https://codeload.github.com/0xOpenBytes/FLet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247842662,"owners_count":21005321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","composition","input","output","spm","swift","testing","transformations","transput"],"created_at":"2024-11-06T10:24:46.962Z","updated_at":"2025-04-08T12:31:51.729Z","avatar_url":"https://github.com/0xOpenBytes.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FLet\n\n*A collection of micro frameworks*\n\n## Frameworks\n\n- [t (FLet.testing)](https://github.com/0xOpenBytes/t): 🧪 Quickly test expectations\n    - `t` is a simple testing framework using closures and errors. You have the ability to create a `suite` that has multiple steps, expectations, and asserts. Expectations can be used to `expect` one or multiple assertions. `t` can be used to test quickly inside a function to make sure something is working as expected. `t` can also be used in unit test if wanted.\n\n- [c (FLet.composition)](https://github.com/0xOpenBytes/c): 📦 Micro Composition using Transformations and Cache\n    - `c` is a simple composition framework. You have the ability to create transformations that are either unidirectional or bidirectional. There is also a cache that values can be set and resolved. `c` can be used anywhere to create transformations or interact with the cache.\n    \n- [o (FLet.transput)](https://github.com/0xOpenBytes/o): Output and Input for File, URL, and Console\n    - `o` is a simple framework to output to a file, url, the console, or even register notification using UserNotifications. `o` can also get input from a file, url, or console. Currently, `o` can be used on macOS, iOS, and watchOS. \n\n## Usage\n\n### Testing\n\n\u003cdetails\u003e \n  \u003csummary\u003eSuite\u003c/summary\u003e \n\n```swift\nt.suite {\n    // Add an expectation that asserting true is true and that 2 is equal to 2\n    try t.expect {\n        try t.assert(true)\n        try t.assert(2, isEqualTo: 2)\n    }\n    \n    // Add an assertion that asserting false is not true\n    try t.assert(notTrue: false)\n    \n    // Add an assertion that \"Hello\" is not equal to \"World\"\n    try t.assert(\"Hello\", isNotEqualTo: \"World\")\n    \n    // Log a message\n    t.log(\"📣 Test Log Message\")\n    \n    // Log a t.error\n    t.log(error: t.error(description: \"Mock Error\"))\n    \n    // Log any error\n    struct SomeError: Error { }\n    t.log(error: SomeError())\n    \n    // Add an assertion to check if a value is nil\n    let someValue: String? = nil\n    try t.assert(isNil: someValue)\n    \n    // Add an assertion to check if a value is not nil\n    let someOtherValue: String? = \"💠\"\n    try t.assert(isNotNil: someOtherValue)\n}\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eExpect\u003c/summary\u003e \n\n```swift \ntry t.expect {\n    let someValue: String? = \"Hello\"\n    try t.assert(isNil: someValue)\n}\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eAssert\u003c/summary\u003e \n\n```swift \ntry t.assert(\"Hello\", isEqualTo: \"World\")\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eLogging\u003c/summary\u003e \n\n```swift \nt.log(\"📣 Test Log Message\")\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eXCTest\u003c/summary\u003e \n\n```swift \n\n// Assert suite is true\nXCTAssert(\n    t.suite {\n        try t.assert(true)\n    }\n)\n\n// Assert expectation is true\nXCTAssertNoThrow(\n    try t.expect(\"true is true and that 2 is equal to 2\") {\n        try t.assert(true)\n        try t.assert(2, isEqualTo: 2)\n    }\n)\n\n// Assert is false\nXCTAssertThrowsError(\n    try t.assert(false)\n)\n```\n\n\u003c/details\u003e \n\n### Composition\n\n\u003cdetails\u003e \n  \u003csummary\u003eLocal Cache\u003c/summary\u003e \n\n```swift \nlet cache = c.cache()\n\ncache.set(value: Double.pi, forKey: \"🥧\")\n\nlet pi: Double = cache.get(\"🥧\") ?? 0\n\ntry t.assert(pi, isEqualTo: .pi)\n\nlet resolvedValue: Double = cache.resolve(\"🥧\")\n\ntry t.assert(resolvedValue, isEqualTo: .pi)\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eGlobal Cache\u003c/summary\u003e \n\n```swift \nlet someCache: Cache = ...\n\n// Set the value of a Cache with any hashable key\nc.set(value: someCache, forKey: \"someCache\")\n\n// Get an optional Cache using any hashable key\nlet anotherCache: Cache? = c.get(0)\n\n// Require that a Cache exist using a `.get` with a force unwrap\nlet requiredCache: Cache = c.resolve(0)\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eTransformation\u003c/summary\u003e \n\n```swift \nlet transformer = c.transformer(\n    from: { string in Int(string) },\n    to: { int in \"\\(String(describing: int))\" }\n)\n\nlet string = transformer.to(3)\nlet int = transformer.from(\"3\")\n\ntry t.assert(transformer.to(int), isEqualTo: string)\n```\n\n\u003c/details\u003e \n\n### Transput\n\n\u003cdetails\u003e \n  \u003csummary\u003eConsole\u003c/summary\u003e \n\n```swift \no.console.out(\"Value to print: \", terminator: \"\") //    (oTests/oTests.swift@7) [testExample()]: Value to print:\no.console.out(o.console.in()) // Type in \"???\";         (oTests/oTests.swift@8) [testExample()]: Optional(\"???\")\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eFile\u003c/summary\u003e \n\n```swift \nlet filename: String = ...\n\n// Write the value 4, an Int, to the file named `filename`. Files using o.file are base64Encoded.\ntry o.file.out(4, filename: filename)\n\n// Asserts\nXCTAssertNoThrow(try o.file.in(filename: filename) as Int)\nXCTAssertEqual(try? o.file.in(filename: filename), 4)\n\n// Delete the File\ntry o.file.delete(filename: filename)\n\n// Assert deletion\nXCTAssertThrowsError(try o.file.in(filename: filename) as Int)\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eURL\u003c/summary\u003e \n\n```swift \nstruct Post: Codable {\n    let userId: Int\n    let id: Int\n    let title: String\n    let body: String\n}\n\n// GET Request\n\no.url.in(\n    url: URL(string: \"api/posts\")!,\n    successHandler: { (posts: [Post], response) in\n        print(posts)\n    }\n)\n\n// POST Request\n\nlet post = Post(userId: 1, id: 1, title: \"First!\", body: \"\")\n\ntry o.url.out(\n    url: URL(string: \"api/posts/\\(post.id)\")!,\n    value: post,\n    successHandler: { data, response in\n        print(response)\n    }\n)\n```\n\n\u003c/details\u003e \n\n\u003cdetails\u003e \n  \u003csummary\u003eNotification\u003c/summary\u003e \n\n```swift\n// Request Notification Authorization \no.notification.requestAuthorization()\n\n// Set UNUserNotificationCenter.current's delegate to `o.notification.delegate`\no.notification.registerDelegate()\n\n// Schedule a Notification\no.notification.post(\n    title: \"Hello!\",\n    subtitle: \"o.notification\",\n    body: \"Woo Hoo!\",\n    trigger: UNTimeIntervalNotificationTrigger(\n        timeInterval: 3,\n        repeats: false\n    )\n)\n```\n\n\u003c/details\u003e \n\n\n### Shorthand Typealias\n```swift\npublic typealias __ = FLet\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xopenbytes%2Fflet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xopenbytes%2Fflet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xopenbytes%2Fflet/lists"}