Giter Club home page Giter Club logo

swift-tagged's Introduction

๐ŸŽฌ www.pointfree.co

Swift 5.7 CI @pointfreeco

This repo contains the full source code for the Point-Free website, a video series exploring advanced programming topics in Swift. The codebase is split into 3 pieces:

  • PointFree: This is the core application, and is responsible for routing requests, loading data and rendering HTML and CSS.
  • Styleguide: This library contains functions and data types for creating a consistent style across the entire website.
  • Server: This is the actual executable server. It uses NIO to handle the low-level server responsibilities, and hands everything else over to the PointFree package.

Point-Free Homepage

Getting Started

Interested in a video tour of the code base?

video poster image

The repo contains an extensive test suite and some playgrounds to explore. To get things running:

  • Open up a terminal window and grab the code:

    git clone https://github.com/pointfreeco/pointfreeco.git
    cd pointfreeco
  • Make sure cmark is installed. You can install it with Homebrew:

    brew install cmark # or your preferred installation method
  • Make sure Postgres is installed and running. It's our database of choice. You can install it with Homebrew:

    brew install postgres # or your preferred installation method
    brew services start postgresql # or your preferred launch method
    make db

    (If you use Postgres.app, EnterpriseDB, or another installation method, please follow some additional instructions in the CPostgreSQL README.)

With the project open in Xcode, you can:

  • Run the server locally
    • Select the Server target
    • Run: Command+R
    • Visit http://localhost:8080
  • Explore our playgrounds
    • Select the PointFree target
    • Build: Command+B
    • Open a playground!

Some fun things to explore

There're a lot of fun things to explore in this repo. For example:

  • We develop web pages in playgrounds for a continuous feedback loop. This is made possible by the fact that the entire server stack is composed of pure functions with side-effects pushed to the boundaries of the application. It allows us to load up any request in isolation, including POST requests, all without ever worrying about doing a side-effect. Server side Swift in a playground

  • We use snapshot testing to capture full data structures in order to verify their correctness. Not only do we do this in the traditional way of taking screenshots of web pages at various break points (e.g. on iPhone and desktop), but we can also snapshot any entire request-to-response lifecycle (e.g. the POST to a signup page does the correct redirect).

โ–ฟ Step
  ResponseEnded

โ–ฟ Request
  POST http://localhost:8080/launch-signup

  [email protected]

โ–ฟ Response
  Status 302 FOUND
  Location: /?success=true

Xcode Color Theme

Like the color theme we use in our episodes? Run make colortheme to install locally!

Related projects

Point-Free uses a bunch of interesting open-source software:

  • ๐Ÿ—บ swift-html: A Swift DSL for type-safe, extensible, and transformable HTML documents.
  • ๐Ÿ•ธ swift-web: A collection of types and functions for dealing with common web server concerns, such as HTML render, CSS preprocessing, middleware and more.
  • ๐ŸŽถ swift-prelude: Offers a standard library for experimental functional programming in Swift.
  • ๐Ÿท swift-tagged: Helps us create strong contracts with our data boundaries, like JSON from GitHub and Stripe, and our PostgreSQL data.
  • ๐Ÿ“ธ swift-snapshot-testing: Powers our testing infrastructure by taking snapshots of various data structures to guarantee the correctness of their output. We use this on everything from middleware to ensure requests are correctly transformed into responses, and even entire web pages to make sure the site looks correct at a variety of sizes (e.g. on iPhone and desktop).

Explore more of our open-source on the Point-Free organization.

Learn More

Brandon gave a talk about most of the core ideas that went into this project at Swift Summit 2017.

The two sides of writing testable code

Find this interesting?

Then check out Point-Free!

License

The content of this project itself is licensed under the CC BY-NC-SA 4.0 license, and the underlying source code used to format and display that content is licensed under the MIT license.

swift-tagged's People

Contributors

buscarini avatar dragna avatar ericlewis avatar justinmilo avatar kaunamohammed avatar maisamilena avatar mattyoung avatar mbrandonw avatar mdarnall avatar pteasima avatar rermolov avatar stephencelis avatar theotherdave avatar tonyarnold avatar volkdmitri 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  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  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  avatar  avatar  avatar  avatar

Watchers

 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

swift-tagged's Issues

Unused dependency in Package.swift?

Hi there ๐Ÿ‘‹

I was noticing that since the merge of #10, my projects using Tagged have more transitive dependencies.
image

This seems due to this dependency specifier in Package.swift:

.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.2.0"),

From what I can see in the rest of Package.swift, none of the library or test targets depend on any targets from XcodeGen. I'm curious if/why this is needed, or if it's something that can be removed.

Thanks!

Unexpected behavior

Hey all, I was just trying something out and ran into an odd issue. I am not entirely sure what the compiler is thinking.

The below code has a problem when it comes to decoding, with JSONDecoder throwing Expected to decode Array<Any> but found a dictionary instead. on files, what is interesting is if we change the type to: [String: File] it works perfectly fine. I didn't dig in to it much, but it seems like the ExpressibleByArrayLiteral conformance is being interpreted incorrectly.

Problem code:

struct Gist {
  let id: Self.ID
  let files: [File.Name: File]

  typealias ID = Tagged<Self, String>
}

extension Gist: Identifiable {}
extension Gist: Codable {}

struct File {
  let filename: Name
  let content: String

  typealias Name = Tagged<Self, String>
}

extension File: Codable {}

Deploy to CocoaPods

Has the latest version (0.4) deployed to CocoaPods?

brad$ pod install --repo-update
Updating local specs repositories
Analyzing dependencies
[!] CocoaPods could not find compatible versions for pod "Tagged":
  In Podfile:
    Tagged (~> 0.4)

None of your spec sources contain a spec satisfying the dependency: `Tagged (~> 0.4)`.

You have either:
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

Decodable issue when using Tagged type as key in Dictionary

Hey @stephencelis and @mbrandonw!

I'm using Tagged in my latest project and it works great but I found the following issue and I'm not sure where the error is.

I'm trying to decode JSON into a Dictionary where the key is a tagged type like this:

let json = """
{
    "data": {
        "key": "value"
    }
}
""".data(using: .utf8)!

struct SomeStruct: Decodable {
    typealias Key = Tagged<SomeStruct, String>
    let data: [Key: String]
}

Strangely I receive this error message on decoding:

typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

When I change the type of the dictionary to [String : String] it works as expected.

Any ideas?

Thank you in advance and keep up the great work with Pointfree.co!

Has anyone been able to get this library working with SQLite.swift?

I get the following error

error: conditional conformance of type 'Tagged<Tag, RawValue>' to protocol 'Value' does not imply conformance to inherited protocol 'Expressible'

both when I try


extension Tagged: Value where Tag == MyTag, RawValue == Int {
  public static var declaredDatatype = Int.declaredDatatype
  public typealias ValueType = Tagged<MyTag, Int>
  public typealias DataType = Int
  public var datatypeValue: Int {
    return self.rawValue
  }

  public static func fromDatatypeValue(_ datatypeValue: Int) -> Tagged<MyTag, Int> {
    return Tagged<MyTag, Int>(datatypeValue)
  }
}

and when I try

extension Tagged: Value where Tag == MyEntity, RawValue == Int {
  public static var declaredDatatype = Int.declaredDatatype
  public typealias ValueType = MyEntity.Id
  public typealias DataType = Int
  public var datatypeValue: Int {
    return self.rawValue
  }

  public static func fromDatatypeValue(_ datatypeValue: Int) -> MyEntity.Id {
    return MyEntity.Id(datatypeValue)
  }
}

So I try to add Expressible to the list of conformances, but I can't figure out how to implement Expressibles requirements. If I don't try to add a function to conform to Expressible, I get a crash.

Fatal error: 'try!' expression unexpectedly raised an error: 
Unexpected null value for column `"my_entity_id"`: 
file .build/checkouts/SQLite.swift/Sources/SQLite/Typed/Query.swift, line 1113

Custom date decoding issue

Hi, I updated to the latest version and I run into an issue with custom date decoding. I think commit 4e607f7 broke that, and now a custom date decoding strategy can't be used for Tagged types, it is simply ignored. This seems like a swift bug to me, but for now I think the best option is to revert that change.

Issue building with Carthage when targeting older iOS SDK

I have an app that targets iOS 11 and when trying the new iOS/Xcode betas I had an issue with Tagged where when it is compiled it targets the latest version and gives messages like this: "Module file's minimum deployment target is ios12.0"

I worked around this by adding an iOS Deployment Target in addition to the macOS Deployment Target already present, this seems to have fixed the issue

CodingKeyRepresentable Conformance

I just discovered that when a dictionary whose keys are a Tagged type, they get encoded as an array of alternating {key}, {value}, ... pairs instead of as an actual object. This is a well known problem with Dictionaries of non "simple" key types (see here, and apparently a (relatively) new solution to this is to have the key type implement the CodingKeyRepresentable protocol.

I was able to add this conformance to Tagged as an extension, but it made me wonder if it makes sense for this conformance to be added to Tagged directly.

Conform to EntityIdentifierConvertible

I tried implementing conformity to EntityIdentifierConvertible in AppIntents, but I couldn't make it work. I'd like to be able to do the following:

import Tagged
struct Route: Identifiable, Codable, Sendable {
	typealias ID = Tagged< Route, String>
	let id: ID
}

import AppIntents
struct RouteEntity: AppEntity, Identifiable {
	var id: Route.ID
	var name: String
	
	// ...
}

Now, as a work-around I define id in the entity as Route.ID.RawValue but that defeats the purpose a bit. What do you think?

Support `SignedInteger` where `RawValue: SignedInteger`

In a current project I am using Tagged as the Interval of a type Note conforming to Strideable. This works great as far as it goes. However, I have a ClosedRange<Note> on which I would like to be able to compute count. This requires Tagged conform to SignedInteger where RawValue: SignedInteger.

Tagged has a number of conditional conformances and does conditionally support Numeric and SignedNumeric, there currently is not support for SignedInteger as far as I can tell. I'm curious if this was intentionally left out, or if it would be reasonable to add?

Are consumers able to override default Codable conditional conformances?

I have a user id that, for legacy reasons, can come back as either a String or an Int and when adding Tagged to handle this case I was hoping to extend Tagged for this type specifically and add a custom Codable implementation to clean this up. The only problem is that the runtime always calls the default conditional conformance implementations rather than my custom ones.

This is a more general Swift question perhaps, but is there a way to override this implementation and make sure the runtime calls my version? Here's the code:

public struct User: Codable {

    public enum UserIdTag {}
    public typealias Id = Tagged<UserIdTag, String>

    let id: Id
}

extension Tagged where Tag == User.UserIdTag, RawValue == String {

    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()

        do {
            try self.init(rawValue: String(container.decode(Int.self)))
        } catch {
            try self.init(rawValue: container.decode(String.self))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(Int(rawValue))
    }
}

New Release?

๐Ÿ‘‹ hi, thank you for this library and your work on point free. Curious if there will be a new release with the changes in master since 0.4.0.

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.