-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e02b98d
Showing
14 changed files
with
671 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
; https://editorconfig.org/ | ||
|
||
root = true | ||
|
||
[*] | ||
insert_final_newline = true | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}] | ||
indent_style = tab | ||
indent_size = 4 | ||
|
||
[*.md] | ||
indent_size = 4 | ||
trim_trailing_whitespace = false | ||
|
||
eclint_indent_style = unset | ||
|
||
[Dockerfile] | ||
indent_size = 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
qr | ||
*.png | ||
.build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
LDFLAGS ?= -s -w | ||
BUILD_DIR ?= .build | ||
|
||
ifeq (, $(shell which golangci-lint)) | ||
$(warning "could not find golangci-lint in $$(PATH), visit: https://golangci-lint.run/usage/install/ for more information") | ||
endif | ||
|
||
.PHONY: lint build install lib test test-lib clean | ||
|
||
lint: | ||
golangci-lint run ./... | ||
|
||
build: $(BUILD_DIR)/bin | ||
go build -ldflags "$(LDFLAGS)" -o $</ | ||
|
||
install: | ||
go install -ldflags "$(LDFLAGS)" | ||
|
||
test: | ||
go test ./... | ||
|
||
lib: $(BUILD_DIR)/lib | ||
export C_INCLUDE_PATH=$<; go build -buildmode=c-shared -ldflags "$(LDFLAGS)" -o $</libqr.so ./internal... | ||
|
||
test-lib: $(BUILD_DIR)/bin/main_test | ||
export LD_LIBRARY_PATH=$(BUILD_DIR)/lib; $< | ||
|
||
$(BUILD_DIR)/bin/main_test: $(BUILD_DIR)/bin $(BUILD_DIR)/lib/libqr.so $(BUILD_DIR)/lib/libqr.h | ||
gcc test/main.c -o $</main_test -L"$(BUILD_DIR)/lib" -I"$(BUILD_DIR)/lib" -lqr | ||
|
||
clean: | ||
rm -rf $(BUILD_DIR) | ||
|
||
$(BUILD_DIR)/lib/libqr.so: lib | ||
|
||
$(BUILD_DIR)/lib/libqr.h: lib | ||
|
||
$(BUILD_DIR): | ||
mkdir -p .build | ||
|
||
$(BUILD_DIR)/bin: $(BUILD_DIR) | ||
mkdir -p $@ | ||
|
||
$(BUILD_DIR)/lib: $(BUILD_DIR) | ||
mkdir -p $@ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# qr | ||
|
||
A lightweight QR encoder CLI and library. | ||
|
||
* Simple to use | ||
* PNG support | ||
* Terminal support | ||
|
||
## Install CLI | ||
|
||
### Using GO | ||
```shell | ||
go install github.com/chey/qr | ||
|
||
qr https://www.example.com | ||
``` | ||
|
||
## Library usage | ||
```shell | ||
go get [-u] github.com/chey/qr | ||
``` | ||
|
||
### Example | ||
|
||
This example prints a small QR code to the terminal using the lowest level of error correction. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/chey/qr/code" | ||
) | ||
|
||
func main() { | ||
qr, _ := code.New("https://www.example.com", code.Low) | ||
qr.Print() | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package code | ||
|
||
import ( | ||
"image" | ||
"image/color" | ||
"image/png" | ||
"io" | ||
"os" | ||
|
||
"rsc.io/qr" | ||
) | ||
|
||
const ( | ||
emptyBlock = "\u0020" | ||
upperHalfBlock = "\u2580" | ||
lowerHalfBlock = "\u2584" | ||
fullBlock = "\u2588" | ||
termBlack = "\033[40m \033[0m" | ||
termWhite = "\033[47m \033[0m" | ||
newline = "\n" | ||
) | ||
|
||
type Level = qr.Level | ||
|
||
const ( | ||
Low = qr.L | ||
Medium = qr.M | ||
High = qr.Q | ||
Highest = qr.H | ||
) | ||
|
||
// Code wraps module import | ||
type Code struct { | ||
*qr.Code | ||
} | ||
|
||
// New creates a new QR Code. | ||
// Error correction levels are 0, 1, 2, 3. | ||
// 3 being the highest level of correction. | ||
func New(text string, level Level) (*Code, error) { | ||
c, err := qr.Encode(text, level) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Code{c}, nil | ||
} | ||
|
||
// Small writes Code to io.Writer w. | ||
// Perfect for terminal. | ||
func (c *Code) Small(w io.Writer) { | ||
for y := -1; y <= c.Size; y += 2 { | ||
for x := -1; x <= c.Size; x++ { | ||
next := c.Black(x, y+1) | ||
curr := c.Black(x, y) | ||
if curr && next { | ||
writeString(w, emptyBlock) | ||
} else if curr && !next { | ||
writeString(w, lowerHalfBlock) | ||
} else if !curr && !next { | ||
if y == c.Size { | ||
writeString(w, upperHalfBlock) | ||
} else { | ||
writeString(w, fullBlock) | ||
} | ||
} else { | ||
writeString(w, upperHalfBlock) | ||
} | ||
} | ||
writeString(w, newline) | ||
} | ||
} | ||
|
||
// Big writes a larger Code to io.Writer w. | ||
// Great for terminal. | ||
func (c *Code) Big(w io.Writer) { | ||
for y := -1; y <= c.Size; y++ { | ||
for x := -1; x <= c.Size; x++ { | ||
if c.Black(x, y) { | ||
writeString(w, termBlack) | ||
} else { | ||
writeString(w, termWhite) | ||
} | ||
} | ||
writeString(w, newline) | ||
} | ||
} | ||
|
||
// Print writes Code to os.Stdout | ||
func (c *Code) Print() { | ||
c.Small(os.Stdout) | ||
} | ||
|
||
// Image returns an image.Image | ||
func (c *Code) Image() image.Image { | ||
return &codeImage{c.Code} | ||
} | ||
|
||
// PNG writes a PNG image to io.Writer w | ||
func (c *Code) PNG(w io.Writer) error { | ||
return png.Encode(w, c.Image()) | ||
} | ||
|
||
// writeString writes string s to io.Writer w | ||
func writeString(w io.Writer, s string) { | ||
if _, err := io.WriteString(w, s); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
// codeImage implements image.Image | ||
type codeImage struct { | ||
*qr.Code | ||
} | ||
|
||
var ( | ||
whiteColor color.Color = color.Gray{0xFF} | ||
blackColor color.Color = color.Gray{0x00} | ||
) | ||
|
||
func (c *codeImage) Bounds() image.Rectangle { | ||
d := (c.Size + 8) * c.Scale | ||
return image.Rect(0, 0, d, d) | ||
} | ||
|
||
func (c *codeImage) At(x, y int) color.Color { | ||
if c.Black(x/c.Scale-4, y/c.Scale-4) { | ||
return blackColor | ||
} | ||
return whiteColor | ||
} | ||
|
||
func (c *codeImage) ColorModel() color.Model { | ||
return color.GrayModel | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package code | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"os" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestCode(t *testing.T) { | ||
_, err := New("chey", 0) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
// max is 7089 for numeric characters so this should fail | ||
// http://en.wikipedia.org/wiki/QR_code | ||
func TestCodeError(t *testing.T) { | ||
if _, err := New(strings.Repeat("1", 7090), 0); err == nil { | ||
t.Error("expeced error") | ||
} | ||
} | ||
|
||
func TestCodeSmall(t *testing.T) { | ||
c, _ := New("chey", 0) | ||
|
||
var buf bytes.Buffer | ||
|
||
c.Small(&buf) | ||
|
||
if buf.String() == "" { | ||
t.Error("got empty code") | ||
} | ||
} | ||
|
||
func TestCodeBig(t *testing.T) { | ||
c, _ := New("chey", 0) | ||
|
||
var buf bytes.Buffer | ||
|
||
c.Big(&buf) | ||
|
||
if buf.String() == "" { | ||
t.Error("got empty code") | ||
} | ||
} | ||
|
||
func TestCodePNG(t *testing.T) { | ||
c, _ := New("chey", 0) | ||
|
||
var buf bytes.Buffer | ||
|
||
err := c.PNG(&buf) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
if buf.String() == "" { | ||
t.Error("got empty png") | ||
} | ||
} | ||
|
||
func TestCodePrint(t *testing.T) { | ||
c, _ := New("chey", 0) | ||
|
||
c.Print() | ||
} | ||
|
||
func TestCodeWriteStringPanic(t *testing.T) { | ||
file := fmt.Sprintf("%s%c%s", t.TempDir(), os.PathSeparator, "qrcode.txt") | ||
fmt.Println(file) | ||
f, _ := os.Create(file) | ||
if err := f.Chmod(0400); err != nil { | ||
t.Error(err) | ||
} | ||
f.Close() | ||
f, _ = os.Open(file) | ||
|
||
recovered := false | ||
|
||
defer func() { | ||
if r := recover(); r != nil { | ||
recovered = true | ||
fmt.Println("Recovered in TestCodeWriteStringPanic", r) | ||
} | ||
}() | ||
writeString(f, "hi") | ||
|
||
if !recovered { | ||
t.Error("expected we could handle a write panic but we didn't") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package code | ||
|
||
var version = "DEV" | ||
|
||
// Version returns version | ||
func Version() string { | ||
return version | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package code | ||
|
||
import "testing" | ||
|
||
func TestVersion(t *testing.T) { | ||
if Version() == "" { | ||
t.Errorf("missing version") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/chey/qr | ||
|
||
go 1.20 | ||
|
||
require rsc.io/qr v0.2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= | ||
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= |
Oops, something went wrong.