Skip to content

Commit

Permalink
fix type bug in websocket example; remove unused code
Browse files Browse the repository at this point in the history
  • Loading branch information
rawhat committed Mar 7, 2024
1 parent 5414d4e commit 5021a86
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 4 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ pub type MyMessage {
fn handle_ws_message(state, conn, message) {
case message {
mist.Text(<<"ping":utf8>>) -> {
let assert Ok(_) = mist.send_text_frame(conn, <<"pong":utf8>>)
mist.Text("ping") -> {
let assert Ok(_) = mist.send_text_frame(conn, "pong")
actor.continue(state)
}
mist.Text(_) | mist.Binary(_) -> {
actor.continue(state)
}
mist.Custom(Broadcast(text)) -> {
let assert Ok(_) = mist.send_text_frame(conn, <<text:utf8>>)
let assert Ok(_) = mist.send_text_frame(conn, text)
actor.continue(state)
}
mist.Closed | mist.Shutdown -> actor.Stop(process.Normal)
Expand Down
23 changes: 23 additions & 0 deletions examples/complete/.github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: test

on:
push:
branches:
- master
- main
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: erlef/setup-beam@v1
with:
otp-version: "26.0.2"
gleam-version: "1.0.0"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam deps download
- run: gleam test
- run: gleam format --check src test
4 changes: 4 additions & 0 deletions examples/complete/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.beam
*.ez
/build
erl_crash.dump
25 changes: 25 additions & 0 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# complete

[![Package Version](https://img.shields.io/hexpm/v/complete)](https://hex.pm/packages/complete)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/complete/)

```sh
gleam add complete
```
```gleam
import complete
pub fn main() {
// TODO: An example of the project in use
}
```

Further documentation can be found at <https://hexdocs.pm/complete>.

## Development

```sh
gleam run # Run the project
gleam test # Run the tests
gleam shell # Run an Erlang shell
```
23 changes: 23 additions & 0 deletions examples/complete/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name = "complete"
version = "1.0.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
# description = ""
# licences = ["Apache-2.0"]
# repository = { type = "github", user = "username", repo = "project" }
# links = [{ title = "Website", href = "https://gleam.run" }]
#
# For a full reference of all the available options, you can have a look at
# https://gleam.run/writing-gleam/gleam-toml/.

[dependencies]
gleam_stdlib = "~> 0.34 or ~> 1.0"
mist = { path = "../.." }
gleam_erlang = "~> 0.24"
gleam_http = "~> 3.5"
gleam_otp = "~> 0.9"

[dev-dependencies]
gleeunit = "~> 1.0"
20 changes: 20 additions & 0 deletions examples/complete/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
{ name = "gleam_http", version = "3.5.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "C2FC3322203B16F897C1818D9810F5DEFCE347F0751F3B44421E1261277A7373" },
{ name = "gleam_otp", version = "0.9.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5FADBBEC5ECF3F8B6BE91101D432758503192AE2ADBAD5602158977341489F71" },
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
{ name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" },
{ name = "glisten", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "glisten", source = "hex", outer_checksum = "BF6C557531E85B13518F3CEA611843C003294C45101D530D1F0DBB0200D51C03" },
{ name = "mist", version = "1.0.0-rc1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "glisten"], source = "local", path = "../.." },
]

[requirements]
gleam_erlang = { version = "~> 0.24"}
gleam_http = { version = "~> 3.5"}
gleam_otp = { version = "~> 0.9"}
gleam_stdlib = { version = "~> 0.34 or ~> 1.0" }
gleeunit = { version = "~> 1.0" }
mist = { path = "../.." }
125 changes: 125 additions & 0 deletions examples/complete/src/complete.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import gleam/bytes_builder
import gleam/erlang/process
import gleam/http/request.{type Request}
import gleam/http/response.{type Response}
import gleam/io
import gleam/iterator
import gleam/option.{None, Some}
import gleam/otp/actor
import gleam/result
import gleam/string
import mist.{type Connection, type ResponseData}

pub fn main() {
// These values are for the Websocket process initialized below
let selector = process.new_selector()
let state = Nil

let not_found =
response.new(404)
|> response.set_body(mist.Bytes(bytes_builder.new()))

let assert Ok(_) =
fn(req: Request(Connection)) -> Response(ResponseData) {
case request.path_segments(req) {
["ws"] ->
mist.websocket(
request: req,
on_init: fn(_conn) { #(state, Some(selector)) },
on_close: fn(_state) { io.println("goodbye!") },
handler: handle_ws_message,
)
["echo"] -> echo_body(req)
["chunk"] -> serve_chunk(req)
["file", ..rest] -> serve_file(req, rest)
["form"] -> handle_form(req)

_ -> not_found
}
}
|> mist.new
|> mist.port(3000)
|> mist.start_http

process.sleep_forever()
}

pub type MyMessage {
Broadcast(String)
}

fn handle_ws_message(state, conn, message) {
case message {
mist.Text("ping") -> {
let assert Ok(_) = mist.send_text_frame(conn, "pong")
actor.continue(state)
}
mist.Text(_) | mist.Binary(_) -> {
actor.continue(state)
}
mist.Custom(Broadcast(text)) -> {
let assert Ok(_) = mist.send_text_frame(conn, text)
actor.continue(state)
}
mist.Closed | mist.Shutdown -> actor.Stop(process.Normal)
}
}

fn echo_body(request: Request(Connection)) -> Response(ResponseData) {
let content_type =
request
|> request.get_header("content-type")
|> result.unwrap("text/plain")

mist.read_body(request, 1024 * 1024 * 10)
|> result.map(fn(req) {
response.new(200)
|> response.set_body(mist.Bytes(bytes_builder.from_bit_array(req.body)))
|> response.set_header("content-type", content_type)
})
|> result.lazy_unwrap(fn() {
response.new(400)
|> response.set_body(mist.Bytes(bytes_builder.new()))
})
}

fn serve_chunk(_request: Request(Connection)) -> Response(ResponseData) {
let iter =
["one", "two", "three"]
|> iterator.from_list
|> iterator.map(bytes_builder.from_string)

response.new(200)
|> response.set_body(mist.Chunked(iter))
|> response.set_header("content-type", "text/plain")
}

fn serve_file(
_req: Request(Connection),
path: List(String),
) -> Response(ResponseData) {
let file_path = string.join(path, "/")

// Omitting validation for brevity
mist.send_file(file_path, offset: 0, limit: None)
|> result.map(fn(file) {
let content_type = guess_content_type(file_path)
response.new(200)
|> response.prepend_header("content-type", content_type)
|> response.set_body(file)
})
|> result.lazy_unwrap(fn() {
response.new(404)
|> response.set_body(mist.Bytes(bytes_builder.new()))
})
}

fn handle_form(req: Request(Connection)) -> Response(ResponseData) {
let _req = mist.read_body(req, 1024 * 1024 * 30)
response.new(200)
|> response.set_body(mist.Bytes(bytes_builder.new()))
}

fn guess_content_type(_path: String) -> String {
"application/octet-stream"
}
12 changes: 12 additions & 0 deletions examples/complete/test/complete_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import gleeunit
import gleeunit/should

pub fn main() {
gleeunit.main()
}

// gleeunit test functions end in `_test`
pub fn hello_world_test() {
1
|> should.equal(1)
}
1 change: 0 additions & 1 deletion src/mist.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ fn convert_body_types(
pub fn start_http(
builder: Builder(Connection, ResponseData),
) -> Result(Subject(supervisor.Message), glisten.StartError) {
builder.handler
fn(req) { convert_body_types(builder.handler(req)) }
|> handler.with_func
|> glisten.handler(fn() { #(handler.new_state(), None) }, _)
Expand Down

0 comments on commit 5021a86

Please sign in to comment.