├── .ebert.yml ├── .formatter.exs ├── .github ├── dependabot.yml ├── renovate.json └── workflows │ ├── elixir.yml │ ├── publish-docs.yml │ └── publish.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── config └── config.exs ├── lib ├── impls │ ├── collectable.ex │ ├── enumerable.ex │ └── inspect.ex └── qex.ex ├── mix.exs ├── mix.lock └── test ├── queue_test.exs └── test_helper.exs /.ebert.yml: -------------------------------------------------------------------------------- 1 | styleguide: plataformatec/linters 2 | engines: 3 | credo: 4 | enabled: true 5 | fixme: 6 | enabled: true 7 | remark-lint: 8 | enabled: true 9 | exclude_paths: 10 | - config 11 | - test 12 | - lib 13 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: mix 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: '19:00' 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["config:recommended"], 3 | "labels": ["dependencies"], 4 | "packageRules": [ 5 | { 6 | "updateTypes": ["minor", "patch", "pin", "digest"], 7 | "automerge": true 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.github/workflows/elixir.yml: -------------------------------------------------------------------------------- 1 | name: Elixir CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | uses: swoosh/actions/.github/workflows/test.yml@main 8 | -------------------------------------------------------------------------------- /.github/workflows/publish-docs.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docs 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | publish: 7 | uses: swoosh/actions/.github/workflows/publish.yml@main 8 | with: 9 | mode: 'docs' 10 | secrets: 11 | HEX_API_KEY: ${{ secrets.HEX_API_KEY }} 12 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | push: 4 | tags: 5 | - 'v*' 6 | workflow_dispatch: 7 | 8 | jobs: 9 | publish: 10 | uses: swoosh/actions/.github/workflows/publish.yml@main 11 | with: 12 | mode: 'package' 13 | secrets: 14 | HEX_API_KEY: ${{ secrets.HEX_API_KEY }} 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | qex-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## v0.5.0 (2018-09-04) 9 | 10 | ### Added 11 | - `first/1`, `first!/1`, `last/1`, `last!/1` 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright (c) 2022 Po Chen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qex 2 | 3 | [![Elixir CI](https://github.com/princemaple/elixir-queue/actions/workflows/elixir.yml/badge.svg)](https://github.com/princemaple/elixir-queue/actions/workflows/elixir.yml) 4 | [![Module Version](https://img.shields.io/hexpm/v/qex.svg)](https://hex.pm/packages/qex) 5 | [![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/qex/) 6 | [![Total Download](https://img.shields.io/hexpm/dt/qex.svg)](https://hex.pm/packages/qex) 7 | [![License](https://img.shields.io/hexpm/l/qex.svg)](https://github.com/princemaple/elixir-queue/blob/master/LICENSE.md) 8 | [![Last Updated](https://img.shields.io/github/last-commit/princemaple/elixir-queue.svg)](https://github.com/princemaple/elixir-queue/commits/master) 9 | 10 | A `:queue` wrapper with improvements in API and addition of Protocol implementations 11 | 12 | ### Protocols 13 | 14 | `Inspect`, `Collectable` and `Enumerable` are implemented, 15 | use Qex with `IO.inspect` and `Enum` functions! 16 | 17 | ### Function signatures 18 | 19 | Parameters are re-ordered to better suit Elixir's awesome `|>` 20 | 21 | ## Installation 22 | 23 | The package can be installed as: 24 | 25 | 1. Add `:qex` to your list of dependencies in `mix.exs`: 26 | 27 | ```elixir 28 | def deps do 29 | [ 30 | {:qex, "~> 0.5"} 31 | ] 32 | end 33 | ``` 34 | 35 | 2. Run `mix deps.get` 36 | 37 | ## How to use 38 | 39 | [Read the docs](https://hexdocs.pm/qex/Qex.html) 40 | 41 | #### Protocols 42 | 43 | ```elixir 44 | iex> inspect Qex.new 45 | "#Qex<[]>" 46 | 47 | iex> Enum.count Qex.new(1..5) 48 | 5 49 | 50 | iex> Enum.empty? Qex.new 51 | true 52 | 53 | iex> Enum.map Qex.new([1, 2, 3]), &(&1 + 1) 54 | [2, 3, 4] 55 | 56 | iex> inspect Enum.into(1..5, %Qex{}) 57 | "#Qex<[1, 2, 3, 4, 5]>" 58 | 59 | # Leverages :queue.member/2 under the hood for performance 60 | iex> Enum.member? Qex.new(1..10_000), 9_999 61 | true 62 | ``` 63 | 64 | #### Create a new queue from a range 65 | 66 | ```elixir 67 | iex> inspect Qex.new(1..3) 68 | "#Qex<[1, 2, 3]>" 69 | ``` 70 | 71 | #### Create a new queue from a list 72 | 73 | ```elixir 74 | iex> inspect Qex.new([1, 2, 3]) 75 | "#Qex<[1, 2, 3]>" 76 | ``` 77 | 78 | #### Add an element to the back of the queue 79 | 80 | ```elixir 81 | iex> q = Qex.new([:mid]) 82 | iex> Enum.to_list Qex.push(q, :back) 83 | [:mid, :back] 84 | ``` 85 | 86 | #### Add an element to the front of the queue 87 | 88 | ```elixir 89 | iex> q = Qex.new([:mid]) 90 | iex> Enum.to_list Qex.push_front(q, :front) 91 | [:front, :mid] 92 | ``` 93 | 94 | #### Get and remove an element from the front of the queue 95 | 96 | ```elixir 97 | iex> q = Qex.new([:front, :mid]) 98 | iex> {{:value, item}, _q} = Qex.pop(q) 99 | iex> item 100 | :front 101 | 102 | iex> q = Qex.new 103 | iex> {empty, _q} = Qex.pop(q) 104 | iex> empty 105 | :empty 106 | ``` 107 | 108 | #### Get and remove an element from the back of the queue 109 | 110 | ```elixir 111 | iex> q = Qex.new([:mid, :back]) 112 | iex> {{:value, item}, _q} = Qex.pop_back(q) 113 | iex> item 114 | :back 115 | 116 | iex> q = Qex.new 117 | iex> {empty, _q} = Qex.pop_back(q) 118 | iex> empty 119 | :empty 120 | ``` 121 | 122 | #### Reverse a queue 123 | 124 | ```elixir 125 | iex> q = Qex.new(1..3) 126 | iex> Enum.to_list q 127 | [1, 2, 3] 128 | iex> Enum.to_list Qex.reverse(q) 129 | [3, 2, 1] 130 | ``` 131 | 132 | #### Split a queue into two, the front n items are put in the first queue 133 | 134 | ```elixir 135 | iex> q = Qex.new 1..5 136 | iex> {q1, q2} = Qex.split(q, 3) 137 | iex> Enum.to_list q1 138 | [1, 2, 3] 139 | iex> Enum.to_list q2 140 | [4, 5] 141 | ``` 142 | 143 | #### Join two queues together 144 | 145 | ```elixir 146 | iex> q1 = Qex.new 1..3 147 | iex> q2 = Qex.new 4..5 148 | iex> Enum.to_list Qex.join(q1, q2) 149 | [1, 2, 3, 4, 5] 150 | ``` 151 | 152 | #### Return the first item 153 | 154 | ```elixir 155 | iex> q1 = Qex.new 1..3 156 | iex> Qex.first(q1) 157 | {:value, 1} 158 | iex> q2 = Qex.new [] 159 | iex> Qex.first(q2) 160 | :empty 161 | 162 | iex> q1 = Qex.new 1..3 163 | iex> Qex.first!(q1) 164 | 1 165 | ``` 166 | 167 | #### Return the last item 168 | 169 | ```elixir 170 | iex> q1 = Qex.new 1..3 171 | iex> Qex.last(q1) 172 | {:value, 3} 173 | iex> q2 = Qex.new [] 174 | iex> Qex.last(q2) 175 | :empty 176 | 177 | iex> q1 = Qex.new 1..3 178 | iex> Qex.last!(q1) 179 | 3 180 | ``` 181 | 182 | ## Why not "Queue"? 183 | 184 | The name is taken... [Hex link](https://hex.pm/packages/queue) 185 | 186 | ## Copyright and License 187 | 188 | Copyright (c) 2022 Po Chen 189 | 190 | This work is free. You can redistribute it and/or modify it under the 191 | terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details. 192 | -------------------------------------------------------------------------------- /config/config.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | -------------------------------------------------------------------------------- /lib/impls/collectable.ex: -------------------------------------------------------------------------------- 1 | defimpl Collectable, for: Qex do 2 | def into(%Qex{} = qex) do 3 | {qex, &push/2} 4 | end 5 | 6 | defp push(q, {:cont, item}), do: Qex.push(q, item) 7 | defp push(q, :done), do: q 8 | defp push(_q, :halt), do: :ok 9 | end 10 | -------------------------------------------------------------------------------- /lib/impls/enumerable.ex: -------------------------------------------------------------------------------- 1 | defimpl Enumerable, for: Qex do 2 | def count(%Qex{data: q}), do: {:ok, :queue.len(q)} 3 | 4 | def member?(%Qex{data: q}, item) do 5 | {:ok, :queue.member(item, q)} 6 | end 7 | 8 | def reduce(%Qex{data: q}, acc, fun) do 9 | Enumerable.List.reduce(:queue.to_list(q), acc, fun) 10 | end 11 | 12 | def slice(%Qex{}), do: {:error, __MODULE__} 13 | end 14 | -------------------------------------------------------------------------------- /lib/impls/inspect.ex: -------------------------------------------------------------------------------- 1 | defimpl Inspect, for: Qex do 2 | import Inspect.Algebra 3 | 4 | def inspect(%Qex{} = q, opts) do 5 | concat(["#Qex<", to_doc(Enum.to_list(q), opts), ">"]) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/qex.ex: -------------------------------------------------------------------------------- 1 | defmodule Qex do 2 | @moduledoc ~S""" 3 | 4 | A `:queue` wrapper with improvements in API and addition of Protocol implementations 5 | 6 | ## Protocols 7 | 8 | `Inspect`, `Collectable` and `Enumerable` are implemented 9 | 10 | iex> inspect Qex.new 11 | "#Qex<[]>" 12 | 13 | iex> Enum.count Qex.new(1..5) 14 | 5 15 | 16 | iex> Enum.empty? Qex.new 17 | true 18 | 19 | iex> Enum.map Qex.new([1, 2, 3]), &(&1 + 1) 20 | [2, 3, 4] 21 | 22 | iex> inspect Enum.into(1..5, %Qex{}) 23 | "#Qex<[1, 2, 3, 4, 5]>" 24 | """ 25 | 26 | @opaque t(type) :: %__MODULE__{:data => :queue.queue(type)} 27 | @opaque t() :: %__MODULE__{:data => :queue.queue()} 28 | 29 | defstruct data: :queue.new() 30 | 31 | @doc """ 32 | Create a new queue from a range 33 | 34 | iex> inspect Qex.new(1..3) 35 | "#Qex<[1, 2, 3]>" 36 | 37 | Create a new queue from a list 38 | 39 | iex> inspect Qex.new([1, 2, 3]) 40 | "#Qex<[1, 2, 3]>" 41 | """ 42 | @spec new([term] | Range.t()) :: t 43 | def new(init_data \\ []) 44 | 45 | def new(x..y) do 46 | %__MODULE__{data: :queue.from_list(Enum.to_list(x..y))} 47 | end 48 | 49 | def new(list) do 50 | %__MODULE__{data: :queue.from_list(list)} 51 | end 52 | 53 | @doc """ 54 | Add an element to the back of the queue 55 | 56 | iex> q = Qex.new([:mid]) 57 | iex> Enum.to_list Qex.push(q, :back) 58 | [:mid, :back] 59 | """ 60 | @spec push(t, term) :: t 61 | def push(%__MODULE__{data: q}, item) do 62 | %__MODULE__{data: :queue.in(item, q)} 63 | end 64 | 65 | @doc """ 66 | Add an element to the front of the queue 67 | 68 | iex> q = Qex.new([:mid]) 69 | iex> Enum.to_list Qex.push_front(q, :front) 70 | [:front, :mid] 71 | """ 72 | @spec push_front(t, term) :: t 73 | def push_front(%__MODULE__{data: q}, item) do 74 | %__MODULE__{data: :queue.in_r(item, q)} 75 | end 76 | 77 | @doc """ 78 | Get and remove an element from the front of the queue 79 | 80 | iex> q = Qex.new([:front, :mid]) 81 | iex> {{:value, item}, _q} = Qex.pop(q) 82 | iex> item 83 | :front 84 | 85 | iex> q = Qex.new 86 | iex> {empty, _q} = Qex.pop(q) 87 | iex> empty 88 | :empty 89 | """ 90 | @spec pop(t) :: {{:value, term}, t} | {:empty, t} 91 | def pop(%__MODULE__{data: q}) do 92 | case :queue.out(q) do 93 | {{:value, v}, q} -> {{:value, v}, %__MODULE__{data: q}} 94 | {:empty, q} -> {:empty, %__MODULE__{data: q}} 95 | end 96 | end 97 | 98 | @spec pop!(t) :: {term, t} | no_return 99 | def pop!(%__MODULE__{data: q}) do 100 | case :queue.out(q) do 101 | {{:value, v}, q} -> {v, %__MODULE__{data: q}} 102 | {:empty, _q} -> raise "Queue is empty" 103 | end 104 | end 105 | 106 | @doc """ 107 | Get and remove an element from the back of the queue 108 | 109 | iex> q = Qex.new([:mid, :back]) 110 | iex> {{:value, item}, _q} = Qex.pop_back(q) 111 | iex> item 112 | :back 113 | 114 | iex> q = Qex.new 115 | iex> {empty, _q} = Qex.pop_back(q) 116 | iex> empty 117 | :empty 118 | """ 119 | @spec pop_back(t) :: {{:value, term}, t} | {:empty, t} 120 | def pop_back(%__MODULE__{data: q}) do 121 | case :queue.out_r(q) do 122 | {{:value, v}, q} -> {{:value, v}, %__MODULE__{data: q}} 123 | {:empty, q} -> {:empty, %__MODULE__{data: q}} 124 | end 125 | end 126 | 127 | @spec pop_back!(t) :: {term, t} | no_return 128 | def pop_back!(%__MODULE__{data: q}) do 129 | case :queue.out_r(q) do 130 | {{:value, v}, q} -> {v, %__MODULE__{data: q}} 131 | {:empty, _q} -> raise "Queue is empty" 132 | end 133 | end 134 | 135 | @doc """ 136 | Reverse a queue 137 | 138 | iex> q = Qex.new(1..3) 139 | iex> Enum.to_list q 140 | [1, 2, 3] 141 | iex> Enum.to_list Qex.reverse(q) 142 | [3, 2, 1] 143 | """ 144 | @spec reverse(t) :: t 145 | def reverse(%__MODULE__{data: q}) do 146 | %__MODULE__{data: :queue.reverse(q)} 147 | end 148 | 149 | @doc """ 150 | Split a queue into two, the front n items are put in the first queue 151 | 152 | iex> q = Qex.new 1..5 153 | iex> {q1, q2} = Qex.split(q, 3) 154 | iex> Enum.to_list q1 155 | [1, 2, 3] 156 | iex> Enum.to_list q2 157 | [4, 5] 158 | """ 159 | @spec split(t, pos_integer) :: {t, t} 160 | def split(%__MODULE__{data: q}, n) do 161 | with {q1, q2} <- :queue.split(n, q) do 162 | {%__MODULE__{data: q1}, %__MODULE__{data: q2}} 163 | end 164 | end 165 | 166 | @doc """ 167 | Join two queues together 168 | 169 | iex> q1 = Qex.new 1..3 170 | iex> q2 = Qex.new 4..5 171 | iex> Enum.to_list Qex.join(q1, q2) 172 | [1, 2, 3, 4, 5] 173 | """ 174 | @spec join(t, t) :: t 175 | def join(%__MODULE__{data: q1}, %__MODULE__{data: q2}) do 176 | %__MODULE__{data: :queue.join(q1, q2)} 177 | end 178 | 179 | @doc """ 180 | Return the first item in the queue in {:value, term} tuple, 181 | return :empty if the queue is empty 182 | 183 | iex> q1 = Qex.new 1..3 184 | iex> Qex.first(q1) 185 | {:value, 1} 186 | iex> q2 = Qex.new [] 187 | iex> Qex.first(q2) 188 | :empty 189 | """ 190 | @spec first(t) :: {:value, term} | :empty 191 | def first(%__MODULE__{data: q}) do 192 | :queue.peek(q) 193 | end 194 | 195 | @doc """ 196 | Retun the first item in the queue, raise if it's empty 197 | 198 | iex> q1 = Qex.new 1..3 199 | iex> Qex.first!(q1) 200 | 1 201 | """ 202 | @spec first!(t) :: term | no_return 203 | def first!(%__MODULE__{data: q}) do 204 | case :queue.peek(q) do 205 | {:value, v} -> v 206 | :empty -> raise "Queue is empty" 207 | end 208 | end 209 | 210 | @doc """ 211 | Return the last item in the queue in {:value, term} tuple, 212 | return :empty if the queue is empty 213 | 214 | iex> q1 = Qex.new 1..3 215 | iex> Qex.last(q1) 216 | {:value, 3} 217 | iex> q2 = Qex.new [] 218 | iex> Qex.last(q2) 219 | :empty 220 | """ 221 | @spec last(t) :: {:value, term} | :empty 222 | def last(%__MODULE__{data: q}) do 223 | :queue.peek_r(q) 224 | end 225 | 226 | @doc """ 227 | Retun the last item in the queue, raise if it's empty 228 | 229 | iex> q1 = Qex.new 1..3 230 | iex> Qex.last!(q1) 231 | 3 232 | """ 233 | @spec last!(t) :: term | no_return 234 | def last!(%__MODULE__{data: q}) do 235 | case :queue.peek_r(q) do 236 | {:value, v} -> v 237 | :empty -> raise "Queue is empty" 238 | end 239 | end 240 | end 241 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Qex.Mixfile do 2 | use Mix.Project 3 | 4 | @source_url "https://github.com/princemaple/elixir-queue" 5 | @version "0.5.1" 6 | 7 | def project do 8 | [ 9 | app: :qex, 10 | name: "Qex", 11 | version: @version, 12 | elixir: "~> 1.9", 13 | build_embedded: Mix.env() == :prod, 14 | start_permanent: Mix.env() == :prod, 15 | deps: deps(), 16 | docs: docs(), 17 | package: package(), 18 | preferred_cli_env: [ 19 | docs: :docs, 20 | "hex.publish": :docs 21 | ] 22 | ] 23 | end 24 | 25 | def application do 26 | [extra_applications: [:logger]] 27 | end 28 | 29 | defp deps do 30 | [{:ex_doc, ">= 0.0.0", only: :docs, runtime: false}] 31 | end 32 | 33 | defp package do 34 | [ 35 | description: 36 | "A `:queue` wrapper with improvements in API and addition of Protocol implementations", 37 | licenses: ["MIT"], 38 | maintainers: ["Po Chen"], 39 | links: %{ 40 | Changelog: "https://hexdocs.pm/qex/changelog.html", 41 | GitHub: @source_url 42 | } 43 | ] 44 | end 45 | 46 | defp docs do 47 | [ 48 | extras: [ 49 | "CHANGELOG.md": [], 50 | "LICENSE.md": [title: "License"], 51 | "README.md": [title: "Overview"] 52 | ], 53 | main: "readme", 54 | canonical: "http://hexdocs.pm/qex", 55 | homepage_url: @source_url, 56 | source_url: @source_url, 57 | source_ref: "v#{@version}" 58 | ] 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, 3 | "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, 4 | "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, 5 | "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, 6 | "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, 7 | "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, 8 | } 9 | -------------------------------------------------------------------------------- /test/queue_test.exs: -------------------------------------------------------------------------------- 1 | defmodule QexTest do 2 | use ExUnit.Case 3 | doctest Qex 4 | end 5 | -------------------------------------------------------------------------------- /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | --------------------------------------------------------------------------------