Overview
Welcome to my personal wiki where I share all of the things that I know. This site is created using mdbook.
Table of Contents
No | Topic | Links |
---|---|---|
1. | Rust | https://ahmadrosid/wiki/rust.html |
2. | Golang | https://ahmadrosid/wiki/go.html |
3. | JavaScript | https://ahmadrosid/wiki/js.html |
4. | Shell | https://ahmadrosid/wiki/shell.html |
Rust
My Project
List of project I Created using rust. Most of this project I Created is because I don't know and I can not find the tool that I need.
- hl - Github-like html Syntax highlighting.
- tpd - Typo Detector for English words.
- json-list - Take json list turn to striing list.
- npr - Find and execute npm script.
- faker-cli - Generate fake data from your terminal.
- rep-cli - Replace text file in Bulk.
CLI - Command Line Application
Collection of comman line app written in Rust that I use.
- bore - bore is a simple CLI tool for making tunnels to localhost
- ripgrep - ripgrep recursively searches directories for a regex pattern while respecting your gitignore
- bat - A cat(1) clone with wings.
- nushell - A new type of shell.
- Helix - A post-modern modal text editor.
GUI - Desktop application
Collection of dekstop app written in Rust.
Golang
Learning Material
Articles
Command Line Application
Javascript
Javascript is my secondary programming language, I use javascript when working on frontend related things.
Opensource Project
Interesting open source project.
Full Stack
- Outline - The fastest wiki and knowledge base for growing teams. Beautiful, feature rich, and markdown compatible.
Library/Framework
- Lexical - Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.
Javascript Playgound
Chearsheets
Generate random string.
function generate(length, password = "") {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_{}/";
Array(length).fill(0).forEach(() => {
password += letters[Math.floor(Math.random() * 64)];
})
return password;
}
// Usage
console.log(generate(32));
Git
Git cheatsheets.
Semantic Commit Messages
Format: <type>(<scope>): <subject>
<scope>
is optional
Example
feat: add hat wobble
^--^ ^------------^
| |
| +-> Summary in present tense.
|
+-------> Type: chore, docs, feat, fix, refactor, style, or test.
More <type>
:
feat
: (new feature for the user, not a new feature for build script)fix
: (bug fix for the user, not a fix to a build script)docs
: (changes to the documentation)style
: (formatting, missing semi colons, etc; no production code change)refactor
: (refactoring production code, eg. renaming a variable)test
: (adding missing tests, refactoring tests; no production code change)chore
: (updating grunt tasks etc; no production code change)
References:
- https://www.conventionalcommits.org/
- https://seesparkbox.com/foundry/semantic_commit_messages
- http://karma-runner.github.io/1.0/dev/git-commit-msg.html
Git Conf
Turn this warning off The file will have its original line endings in your working directory
git config core.autocrlf true
git sync local repository with remote
git fetch --prune
update commit authro
git commit --amend --author="Author Name <some@mail.com>" --no-edit
# or in short
git commit --amend --reset-author
Shell Script
- asdf - Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more
Cheatsheets
Check if command exists or not.
if !(command -v go); then
# Do something
fi
Check if folder exists or not.
if ! test -d "$BUILD_FOLDER"; then
mkdir $BUILD_FOLDER
fi
Archive
Extract tar.gz
tar -xvzf filename.tar.gz
Database
MySQL Cheatsheets
Quick cheatsheat for doing mysql query for CRUD operation.
Create Database
CREATE DATABASE db_name;
Create Table
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(30) NOT NULL,
last_name VARCHAR(30) NOT NULL,
email VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
Insert
INSERT INTO users(first_name, last_name, email)
VALUES ("Ahmad","Rosid","sample@mail.com");
Cheatsheets
Rust
Golang
- Array String Contains
- Convert Size To Bytes
- Format File Size
- Get Current Dir
- Get Directory Size
- Parse Dynamic Json
- Parse Float64
- Print All Mux Routes
- Read File To String
- Repeat Execute
JavaScript
Filter vector to unique list.
// from
vec![1,1,2,3]
// to
vec![1,2,3]
data
.into_iter()
.collect::<HashSet<_>>()
.into_iter()
.collect::<Vec<_>>()
Read file to string in Rust.
Read to string
let file = "data.txt"
let data = std::fs::read_to_string(file).expect(&format!("Filed reading file {}", file));
Read file line by line
let file = File::open(path);
if let Ok(file) = file {
let mut reader = BufReader::new(file);
loop {
let mut line = String::new();
match reader.read_line(&mut line) {
Ok(_) => {
if line.is_empty() {
break;
}
// do anything with line
}
_ => break,
};
}
}
Watch file changes with inotify.
Cargo.toml
[dependencies]
notify = "4"
Code:
extern crate notify;
use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;
use std::time::Duration;
use std::path::Path;
fn watch(file_path: &str) -> notify::Result<()> {
let (tx, rx) = channel();
let delay = 300;
let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_millis(delay))?;
watcher.watch(Path::new(&file_path), RecursiveMode::NonRecursive)?;
loop {
let event = match rx.recv() {
Ok(event) => event,
Err(err) => {
println!("Config watcher channel dropped unexpectedly: {}", err);
break;
}
};
match event {
DebouncedEvent::Rename(_, path)
| DebouncedEvent::Write(path)
| DebouncedEvent::Create(path)
| DebouncedEvent::Chmod(path) => {
// do with file changes
}
_ => (),
}
}
Ok(())
}
Write string to file path.
use std::io::Write;
fn write_file(content: &String, file_name: &str) {
let cwd = std::env::current_dir().unwrap();
let mut file = std::fs::File::create(format!("{}/{}", cwd.to_str().unwrap(), file_name)).unwrap();
write!(&mut file, "{}", content).unwrap();
}
Golang: Check if some array sting contains a given string.
package main
import "sort"
func ArrayStringContain(array []string, s string) bool {
idx := sort.SearchStrings(array, s)
return idx < len(array) && array[idx] == s
}
func main() {
var data = []string{"work", "from", "home"}
if ArrayStringContain(data, "home") {
println("Yes it contain 'home'!")
}
}
Convert size to bytes 1KiB to 1024
.
import (
"strings"
"strconv"
)
func Pow(x int64, y int) int64 {
if y == 0 {
return 1
}
result := x
for n := 1; n < y; n++ {
result = result * x
}
return result
}
func ConvertSizeToBytes(s string) (string, error) {
// make lowercase so units detection always works
s = strings.TrimSpace(strings.ToLower(s))
// first look for binary units
for _, unit := range units2 {
if strings.HasSuffix(s, unit) {
s = strings.TrimSuffix(s, unit)
if i, err := strconv.ParseInt(s, 10, 0); err != nil {
return "", fmt.Errorf("invalid size value '%s': %v", s, err)
} else {
i = i * Pow(1024, lookupTable2[unit])
s = strconv.FormatInt(i, 10)
return s, nil
}
}
}
// fall back to SI units
for _, unit := range units10 {
if strings.HasSuffix(s, unit) {
s = strings.TrimSuffix(s, unit)
if i, err := strconv.ParseInt(s, 10, 0); err != nil {
return "", fmt.Errorf("invalid size value '%s': %v", s, err)
} else {
i = i * Pow(1000, lookupTable10[unit])
s = strconv.FormatInt(i, 10)
return s, nil
}
}
}
// no valid units found, so ensure the value is a number
if _, err := strconv.ParseUint(s, 10, 64); err != nil {
return "", fmt.Errorf("invalid size value '%s': %v", s, err)
}
return s, nil
}
How to use?
var k = "1KiB"
s, err := ConvertSizeToBytes(k)
// s = 1024
Golang: Format byte size to human readable text.
import "fmt"
var sizes = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
func FormatFileSize(s float64, base float64) string {
unitsLimit := len(sizes)
i := 0
for s >= base && i < unitsLimit {
s = s / base
i++
}
f := "%.0f %s"
if i > 1 {
f = "%.2f %s"
}
return fmt.Sprintf(f, s, sizes[i])
}
How to use:
var size = 452984832
fmt.Printf("%s\n", FormatFileSize(float64(size), 1024.0)) // 432.00 MB
Golang: Get current working direactory path.
import (
"os"
"fmt"
)
func GetCurrentDir() string {
dir, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(-1)
}
return dir
}
Golang: Get directory size recursively.
import (
"path/filepath"
"os"
)
const notRegularFileMode os.FileMode = os.ModeDir | os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular
func GetDirectorySize(path string) (int64, error) {
var size int64
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if info != nil && (info.Mode()¬RegularFileMode) == 0 {
size += info.Size()
}
return err
})
return size, err
}
Most of the time we will parse JSON data to struct.
type User struct {
Username string `json:"username"`
Email string `json:"email"`
}
But if you have JSON data like this, you can not parse that directly to the struct.
{
"0": {
"username":"ahmad",
"email":"ahmad@mail.com",
},
"1": {
"username":"ahmad1",
"email":"ahmad1@mail.com",
}
}
So to solve this you can create map to user.
type Response map[string]User
So you can parse it like this.
import (
"strings"
"encoding/json"
)
func Parse(data string) {
dec := json.NewDecoder(strings.NewReader(data))
var response Response
dec.Decode(&response)
response["0"].username // ahmad
response["1"].username // ahmad1
}
Golang: Convert interface{}
to float64.
import (
"fmt"
"math"
)
func parseFloat64(unk interface{}) (float64, error) {
switch i := unk.(type) {
case float64:
return i, nil
case float32:
return float64(i), nil
case int64:
return float64(i), nil
case int32:
return float64(i), nil
case int:
return float64(i), nil
case uint64:
return float64(i), nil
case uint32:
return float64(i), nil
case uint:
return float64(i), nil
default:
return math.NaN(), fmt.Errorf("failed to parse to float")
}
}
Collect all gorilla mux routes and print to stdout.
import (
"fmt"
"log"
"net/http"
"strings"
"github.com/gorilla/mux"
)
func PrintRoute(router *mux.Router) {
router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
t, err := route.GetPathTemplate()
if err != nil {
log.Println(err)
return err
}
fmt.Println(strings.Repeat("| ", len(ancestors)), t)
return nil
})
}
Usage :
func handler(w http.ResponseWriter, r *http.Request) {
return
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.HandleFunc("/products", handler)
r.HandleFunc("/articles", handler)
r.HandleFunc("/blog", handler)
r.HandleFunc("/blog/post", handler)
r.HandleFunc("/blog/post/{slug}", handler)
r.HandleFunc("/articles/{id}", handler)
PrintRoute(r)
}
Golang: Read file line by line and return string.
import (
"os"
"bufio"
)
func ReadFileToString(filename string) {
fs, err := os.Open(filename)
if err != nil {
log.Fatalf("Failed to open file %s\n", filename)
}
defer fs.Close()
scanner := bufio.NewScanner(fs)
var data string
for scanner.Scan() {
data += scanner.Text() + "\n"
}
return data
}
Or if you want to use shorter version.
import (
"op/ioutil"
"log"
"fmt"
)
func main() {
result, err := ioutil.ReadFile("thermopylae.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(result))
}
For scaning string word by word.
import (
"fmt"
"os"
"bufio"
)
func main() {
file, err := os.Open("thermopylae.txt")
if err != nil {
fmt.Println(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
}
}
Repeat executes f every interval seconds until stopc is closed. It executes f once right after being called.
import (
"time"
)
func RepeatExecute(interval time.Duration, stopc <-chan struct{}, f func() error) error {
tick := time.NewTicker(interval)
defer tick.Stop()
for {
if err := f(); err != nil {
return err
}
select {
case <-stopc:
return nil
case <-tick.C:
}
}
}
How to use?
func Run(ctx context.Context, interval time.Duration) error {
return RepeatExecute(interval, ctx.Done(), func() error {
err := someOperation()
if err != nil {
return err
}
return nil
})
}
Javascript: Create directory recursively if not exists.
function createFileIfNotExists(dirName) {
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName, {
recursive: true,
});
}
}
Convert a date to a relative time string, such as "a minute ago", "in 2 hours", "yesterday", "3 months ago", etc.
function getRelativeTimeString(date, lang) {
const minute = 60;
const hour = minute * 60;
const day = hour * 24;
const week = day * 7;
const month = day * 30;
const year = day * 365;
const time = date instanceof Date ? date.getTime() : date;
const delta = Math.round((time - Date.now()) / 1000);
const absoluteDelta = Math.abs(delta);
const times = [
[minute, "second", 1],
[hour, "minute", minute],
[day, "hour", hour],
[week, "day", day],
[month, "week", week],
[year, "month", month],
[Infinity, "year", year],
];
let divider = year;
let timeType = "year";
for (const [num, timeInterval, div] of times) {
if (absoluteDelta < num) {
divider = div;
timeType = timeInterval;
break;
}
}
const rtf = new Intl.RelativeTimeFormat(lang, { numeric: "auto" });
return rtf.format(Math.floor(delta / divider), timeType);
}
Usage:
getRelativeTimeString(Date.now() + 1000) // in 1 second
getRelativeTimeString(Date.now() + 100000000) // tomorrow
Next.js: Use this to catch all routes inside sub directory, so don't need to create sub directory for each slashed URL.
File:
pages/blog/[...slug].js
Url will be:
/blog/post
/blog/post/one
/blog/post/two/three.xyz
Code:
export async function getStaticPaths() {
return {
paths: [
{ params: { slug: ["post"] } },
{ params: { slug: ["post", "one"] } },
{ params: { slug: ["post", "two", "three.xyz"] } }
],
fallback: false
};
}
export async function getStaticProps({ params }) {
const postData = await getDataBySlug(params.slug)
return {
props: {
postData
}
}
}
export default function Post({ postData }) {
return (...)
}
Javascript: Walk directory recursively.
const fs = require("fs");
const path = require("path");
async function* walk(dir) {
for await (const d of await fs.promises.opendir(dir)) {
const entry = path.join(dir, d.name);
if (d.isDirectory()) yield* walk(entry);
else if (d.isFile()) yield entry;
}
}
// Then, use it with a simple async for loop
async function main() {
const dir = "."
for await (const p of walk(dir))
console.log(p)
}