1602473749
Riccardo D’Ambrosio recently released RSLint, a linter for JavaScript that is written entirely in Rust. RSLint strives to be as fast as possible, customizable, and easy to use. RSLint is still in the early phase of its development and features basic Visual Studio Code integration.
RSLint’s creator described his motivation as follows:
The project is a fully-fledged JavaScript linter but written from scratch in Rust. I felt existing linters were too limiting and slow and decided to try and make one myself with some key points in mind:
speed: file loading, file linting, rule running are all parallelized
very rustc-like and friendly errors (including labels, notes)
error recovery: source code can be linted no matter how wrong it is
[…]
more powerful directives
As any linter, RSLint strives to help developers enforce good practices and flag programming errors, bugs, stylistic errors, and suspicious constructs. Linters are generally used within a code editor to provide real-time feedback while editing. Users working on a large codebase with a sizable number of configured lint rules may benefit from the provided speed improvement in the form of faster real-time feedback.
Similarly, developer experience may be enhanced by friendly and explanatory message errors when a lint rule fails, especially so when rules are complex or refer to several other syntactic entities.
D’Ambrosio emphasized the error recovery capabilities of RSLint that are allegedly absent from some known linters:
Error recovery refers to a parser being able to take in incorrect source code, and still parse a mostly correct AST Abstract Syntax Treeout of it. Most linters do not attempt this at all, for example, espree, and swc_ecmascript (ESLint and deno_lint’s parsers respectively) make no attempt at recovery. When the parsers encounter an error they return an Err result and quit parsing, producing no AST.
[…] This means it is impossible for the linters to lint wrong code, which is an amazing feature for on-the-fly linting in things such as IDEs.
RSLint can parse the following code:
if true {
/* */
} else {
/* */
}
and lints it as follows:
error[SyntaxError]: Expected token `L_PAREN` but instead found `TRUE_KW`
┌─ tests\main.js:1:4
│
1 │ if true {
│ ^^^^ Unexpected
error[SyntaxError]: Expected token `R_PAREN` but instead found `L_CURLY`
┌─ tests\main.js:1:9
│
1 │ if true {
│ ^ Unexpected
error[no-constant-condition]: Unexpected constant condition
┌─ tests\main.js:1:4
│
1 │ if true {
│ ^^^^ this condition is always truthy...
2 │ /* */
3 │ } else {
│ ┌────────'
4 │ │ /* */
5 │ │ }
│ └─' ...which makes this unreachable
#rust #javascript #programming #developer #web-development
1602473749
Riccardo D’Ambrosio recently released RSLint, a linter for JavaScript that is written entirely in Rust. RSLint strives to be as fast as possible, customizable, and easy to use. RSLint is still in the early phase of its development and features basic Visual Studio Code integration.
RSLint’s creator described his motivation as follows:
The project is a fully-fledged JavaScript linter but written from scratch in Rust. I felt existing linters were too limiting and slow and decided to try and make one myself with some key points in mind:
speed: file loading, file linting, rule running are all parallelized
very rustc-like and friendly errors (including labels, notes)
error recovery: source code can be linted no matter how wrong it is
[…]
more powerful directives
As any linter, RSLint strives to help developers enforce good practices and flag programming errors, bugs, stylistic errors, and suspicious constructs. Linters are generally used within a code editor to provide real-time feedback while editing. Users working on a large codebase with a sizable number of configured lint rules may benefit from the provided speed improvement in the form of faster real-time feedback.
Similarly, developer experience may be enhanced by friendly and explanatory message errors when a lint rule fails, especially so when rules are complex or refer to several other syntactic entities.
D’Ambrosio emphasized the error recovery capabilities of RSLint that are allegedly absent from some known linters:
Error recovery refers to a parser being able to take in incorrect source code, and still parse a mostly correct AST Abstract Syntax Treeout of it. Most linters do not attempt this at all, for example, espree, and swc_ecmascript (ESLint and deno_lint’s parsers respectively) make no attempt at recovery. When the parsers encounter an error they return an Err result and quit parsing, producing no AST.
[…] This means it is impossible for the linters to lint wrong code, which is an amazing feature for on-the-fly linting in things such as IDEs.
RSLint can parse the following code:
if true {
/* */
} else {
/* */
}
and lints it as follows:
error[SyntaxError]: Expected token `L_PAREN` but instead found `TRUE_KW`
┌─ tests\main.js:1:4
│
1 │ if true {
│ ^^^^ Unexpected
error[SyntaxError]: Expected token `R_PAREN` but instead found `L_CURLY`
┌─ tests\main.js:1:9
│
1 │ if true {
│ ^ Unexpected
error[no-constant-condition]: Unexpected constant condition
┌─ tests\main.js:1:4
│
1 │ if true {
│ ^^^^ this condition is always truthy...
2 │ /* */
3 │ } else {
│ ┌────────'
4 │ │ /* */
5 │ │ }
│ └─' ...which makes this unreachable
#rust #javascript #programming #developer #web-development
1663559281
Learn how to create a to-do list app with local storage using HTML, CSS and JavaScript. Build a Todo list application with HTML, CSS and JavaScript. Learn the basics to JavaScript along with some more advanced features such as LocalStorage for saving data to the browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>To Do List With Local Storage</title>
<!-- Font Awesome Icons -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
/>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap"
rel="stylesheet"
/>
<!-- Stylesheet -->
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div id="new-task">
<input type="text" placeholder="Enter The Task Here..." />
<button id="push">Add</button>
</div>
<div id="tasks"></div>
</div>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #0b87ff;
}
.container {
width: 90%;
max-width: 34em;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
}
#new-task {
position: relative;
background-color: #ffffff;
padding: 1.8em 1.25em;
border-radius: 0.3em;
box-shadow: 0 1.25em 1.8em rgba(1, 24, 48, 0.15);
display: grid;
grid-template-columns: 9fr 3fr;
gap: 1em;
}
#new-task input {
font-family: "Poppins", sans-serif;
font-size: 1em;
border: none;
border-bottom: 2px solid #d1d3d4;
padding: 0.8em 0.5em;
color: #111111;
font-weight: 500;
}
#new-task input:focus {
outline: none;
border-color: #0b87ff;
}
#new-task button {
font-family: "Poppins", sans-serif;
font-weight: 500;
font-size: 1em;
background-color: #0b87ff;
color: #ffffff;
outline: none;
border: none;
border-radius: 0.3em;
cursor: pointer;
}
#tasks {
background-color: #ffffff;
position: relative;
padding: 1.8em 1.25em;
margin-top: 3.8em;
width: 100%;
box-shadow: 0 1.25em 1.8em rgba(1, 24, 48, 0.15);
border-radius: 0.6em;
}
.task {
background-color: #ffffff;
padding: 0.3em 0.6em;
margin-top: 0.6em;
display: flex;
align-items: center;
border-bottom: 2px solid #d1d3d4;
cursor: pointer;
}
.task span {
font-family: "Poppins", sans-serif;
font-size: 0.9em;
font-weight: 400;
}
.task button {
color: #ffffff;
padding: 0.8em 0;
width: 2.8em;
border-radius: 0.3em;
border: none;
outline: none;
cursor: pointer;
}
.delete {
background-color: #fb3b3b;
}
.edit {
background-color: #0b87ff;
margin-left: auto;
margin-right: 3em;
}
.completed {
text-decoration: line-through;
}
//Initial References
const newTaskInput = document.querySelector("#new-task input");
const tasksDiv = document.querySelector("#tasks");
let deleteTasks, editTasks, tasks;
let updateNote = "";
let count;
//Function on window load
window.onload = () => {
updateNote = "";
count = Object.keys(localStorage).length;
displayTasks();
};
//Function to Display The Tasks
const displayTasks = () => {
if (Object.keys(localStorage).length > 0) {
tasksDiv.style.display = "inline-block";
} else {
tasksDiv.style.display = "none";
}
//Clear the tasks
tasksDiv.innerHTML = "";
//Fetch All The Keys in local storage
let tasks = Object.keys(localStorage);
tasks = tasks.sort();
for (let key of tasks) {
let classValue = "";
//Get all values
let value = localStorage.getItem(key);
let taskInnerDiv = document.createElement("div");
taskInnerDiv.classList.add("task");
taskInnerDiv.setAttribute("id", key);
taskInnerDiv.innerHTML = `<span id="taskname">${key.split("_")[1]}</span>`;
//localstorage would store boolean as string so we parse it to boolean back
let editButton = document.createElement("button");
editButton.classList.add("edit");
editButton.innerHTML = `<i class="fa-solid fa-pen-to-square"></i>`;
if (!JSON.parse(value)) {
editButton.style.visibility = "visible";
} else {
editButton.style.visibility = "hidden";
taskInnerDiv.classList.add("completed");
}
taskInnerDiv.appendChild(editButton);
taskInnerDiv.innerHTML += `<button class="delete"><i class="fa-solid fa-trash"></i></button>`;
tasksDiv.appendChild(taskInnerDiv);
}
//tasks completed
tasks = document.querySelectorAll(".task");
tasks.forEach((element, index) => {
element.onclick = () => {
//local storage update
if (element.classList.contains("completed")) {
updateStorage(element.id.split("_")[0], element.innerText, false);
} else {
updateStorage(element.id.split("_")[0], element.innerText, true);
}
};
});
//Edit Tasks
editTasks = document.getElementsByClassName("edit");
Array.from(editTasks).forEach((element, index) => {
element.addEventListener("click", (e) => {
//Stop propogation to outer elements (if removed when we click delete eventually rhw click will move to parent)
e.stopPropagation();
//disable other edit buttons when one task is being edited
disableButtons(true);
//update input value and remove div
let parent = element.parentElement;
newTaskInput.value = parent.querySelector("#taskname").innerText;
//set updateNote to the task that is being edited
updateNote = parent.id;
//remove task
parent.remove();
});
});
//Delete Tasks
deleteTasks = document.getElementsByClassName("delete");
Array.from(deleteTasks).forEach((element, index) => {
element.addEventListener("click", (e) => {
e.stopPropagation();
//Delete from local storage and remove div
let parent = element.parentElement;
removeTask(parent.id);
parent.remove();
count -= 1;
});
});
};
//Disable Edit Button
const disableButtons = (bool) => {
let editButtons = document.getElementsByClassName("edit");
Array.from(editButtons).forEach((element) => {
element.disabled = bool;
});
};
//Remove Task from local storage
const removeTask = (taskValue) => {
localStorage.removeItem(taskValue);
displayTasks();
};
//Add tasks to local storage
const updateStorage = (index, taskValue, completed) => {
localStorage.setItem(`${index}_${taskValue}`, completed);
displayTasks();
};
//Function To Add New Task
document.querySelector("#push").addEventListener("click", () => {
//Enable the edit button
disableButtons(false);
if (newTaskInput.value.length == 0) {
alert("Please Enter A Task");
} else {
//Store locally and display from local storage
if (updateNote == "") {
//new task
updateStorage(count, newTaskInput.value, false);
} else {
//update task
let existingCount = updateNote.split("_")[0];
removeTask(updateNote);
updateStorage(existingCount, newTaskInput.value, false);
updateNote = "";
}
count += 1;
newTaskInput.value = "";
}
});
#html #css #javascript
1643176207
Serde
*Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.*
You may be looking for:
#[derive(Serialize, Deserialize)]
Click to show Cargo.toml. Run this code in the playground.
[dependencies]
# The core APIs, including the Serialize and Deserialize traits. Always
# required when using Serde. The "derive" feature is only required when
# using #[derive(Serialize, Deserialize)] to make Serde work with structs
# and enums defined in your crate.
serde = { version = "1.0", features = ["derive"] }
# Each data format lives in its own crate; the sample code below uses JSON
# but you may be using a different one.
serde_json = "1.0"
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
Serde is one of the most widely used Rust libraries so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the #rust-questions or #rust-beginners channels of the unofficial community Discord (invite: https://discord.gg/rust-lang-community), the #rust-usage or #beginners channels of the official Rust Project Discord (invite: https://discord.gg/rust-lang), or the #general stream in Zulip. For asynchronous, consider the [rust] tag on StackOverflow, the /r/rust subreddit which has a pinned weekly easy questions post, or the Rust Discourse forum. It's acceptable to file a support issue in this repo but they tend not to get as many eyes as any of the above and may get closed without a response after some time.
Download Details:
Author: serde-rs
Source Code: https://github.com/serde-rs/serde
License: View license
1595534040
A Rust crate for writing fast JavaScript and TypeScript linters.
This crate powers deno lint, but is not Deno specific and can be used to write linters for Node as well.
NOTE Work-in-progress
Current focus is on getting _recommended_
set of rules from ESLint and _@typescript-eslint_
working out of the box.
See the roadmap
Blazing fast, see comparison with ESLint:
[
{
"name": "deno_lint",
"totalMs": 830.5838349999995,
"runsCount": 5,
"runsAvgMs": 166.1167669999999,
"runsMs": [
163.71872200000007,
160.46893499999987,
169.2397719999999,
167.75393099999974,
169.40247499999987
]
},
{
"name": "eslint",
"totalMs": 11783.570954999997,
"runsCount": 5,
"runsAvgMs": 2356.7141909999996,
"runsMs": [
2559.053129,
2383.412156999999,
2261.1746249999997,
2306.645263999999,
2273.28578
]
}
]
Benchmarks are run during CI on Ubuntu, using the same set of rules for both linters. Test subject is [_oak_](https://github.com/oakserver/oak)
_ server_ consisting of about 50 files. See [_./benchmarks/_](https://github.com/denoland/deno_lint/blob/master/benchmarks)
directory for more info.
To ignore whole file // deno-lint-ignore-file
directive should placed at the top of the file.
// deno-lint-ignore-file
function foo(): any {
// ...
}
Ignore directive must be placed before first stament or declaration:
// Copyright 2020 the Deno authors. All rights reserved. MIT license.
/**
* Some JS doc
**/
// deno-lint-ignore-file
import { bar } from "./bar.js";
function foo(): any {
// ...
}
To ignore certain diagnostic // deno-lint-ignore <codes...>
directive should be placed before offending line.
// deno-lint-ignore no-explicit-any
function foo(): any {
// ...
}
// deno-lint-ignore no-explicit-any explicit-function-return-type
function bar(a: any) {
// ...
}
Specyfing rule code that will be ignored is required.
examples/dlint/main.rs
provides a minimal standalone binary demonstrating how deno_lint
can be used as a crate.
$ ▶ target/debug/examples/dlint ../deno/std/http/server.ts ../deno/std/http/file_server.ts
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:93:14
|
93 | } catch {}
| ^^
|
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:111:44
|
111 | while ((await body.read(buf)) !== null) {}
| ^^
|
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:120:41
|
120 | constructor(public listener: Listener) {}
| ^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:5:0
|
5 | // TODO Stream responses instead of reading them into memory.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:6:0
|
6 | // TODO Add tests like these:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:137:0
|
137 | // TODO: simplify this after deno.stat and deno.readDir are fixed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(no-empty) Empty block statement
--> ../deno/std/http/file_server.ts:155:16
|
155 | } catch (e) {}
| ^^
|
Found 7 problems
For more concrete implementation visit deno
Make sure to have latest stable version of Rust installed (1.44.0).
// check version
$ rustc --version
rustc 1.44.0 (49cae5576 2020-06-01)
// build all targets
$ cargo build --all-targets
// test it
$ cargo test
Prerequisites:
$ RUSTFLAGS='-g' cargo build --release --all-targets # build target
$ sudo perf record --call-graph dwarf ./target/release/examples/dlint benchmarks/oak/**.ts # create performance profile
$ perf script | stackcollapse-perf | rust-unmangle | flamegraph > flame.svg # generate flamegraph
These commands can take a few minutes to run.
If you are going to work on an issue, mention so in the issue comments before you start working on the issue.
Please be professional in the forums. We follow Rust’s code of conduct (CoC) Have a problem? Email ry@tinyclouds.org.
Ask for help in the community chat room.
Before submitting, please make sure the following is done:
cargo test
passes.deno run --allow-run tools/format.ts
deno run --allow-run tools/lint.ts
passes.Author: denoland
GitHub: https://github.com/denoland/deno_lint
#deno #nodejs #javascript #typescript #rust
1658227980
deno_lint
A Rust crate for writing fast JavaScript and TypeScript linters.
This crate powers deno lint
, but is not Deno specific and can be used to write linters for Node as well.
Supports recommended
set of rules from ESLint and @typescript-eslint
out of the box with no config.
Blazing fast, see comparison with ESLint:
[
{
"name": "deno_lint",
"totalMs": 105.3750100000002,
"runsCount": 5,
"measuredRunsAvgMs": 21.07500200000004,
"measuredRunsMs": [
24.79783199999997,
19.563640000000078,
20.759051999999883,
19.99068000000011,
20.26380600000016
]
},
{
"name": "eslint",
"totalMs": 11845.073306000002,
"runsCount": 5,
"measuredRunsAvgMs": 2369.0146612000003,
"measuredRunsMs": [
2686.1039550000005,
2281.501061,
2298.6185210000003,
2279.5962849999996,
2299.2534840000008
]
}
]
Benchmarks are run during CI on Ubuntu, using the same set of rules for both linters. Test subject is oak
server consisting of about 50 files. See ./benchmarks/
directory for more info.
If you want to use deno_lint
with Node, please refer to @node-rs/deno-lint
package which provides programmatic API as well as Webpack loader for deno_lint
.
examples/dlint/main.rs
provides a minimal standalone binary demonstrating how deno_lint
can be used as a crate.
# Build standalone binary
$ cargo build --example dlint
$ ./target/debug/examples/dlint --help
dlint
USAGE:
dlint <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
rules
run
$ ./target/debug/examples/dlint run ../deno/std/http/server.ts ../deno/std/http/file_server.ts
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:93:14
|
93 | } catch {}
| ^^
|
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:111:44
|
111 | while ((await body.read(buf)) !== null) {}
| ^^
|
(no-empty) Empty block statement
--> ../deno/std/http/server.ts:120:41
|
120 | constructor(public listener: Listener) {}
| ^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:5:0
|
5 | // TODO Stream responses instead of reading them into memory.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:6:0
|
6 | // TODO Add tests like these:
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(ban-untagged-todo) TODO should be tagged with (@username) or (#issue)
--> ../deno/std/http/file_server.ts:137:0
|
137 | // TODO: simplify this after deno.stat and deno.readDir are fixed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
(no-empty) Empty block statement
--> ../deno/std/http/file_server.ts:155:16
|
155 | } catch (e) {}
| ^^
|
Found 7 problems
For more concrete implementation visit deno
Make sure to have latest stable version of Rust installed (1.56.0).
// check version
$ rustc --version
rustc 1.56.0 (09c42c458 2021-10-18)
// build all targets
$ cargo build --all-targets
// test it
$ cargo test
Prerequisites:
perf
, stackcollapse-perf
, c++filt
and flamegraph
$ RUSTFLAGS='-g' cargo build --release --all-targets # build target
$ sudo perf record --call-graph dwarf ./target/release/examples/dlint benchmarks/oak/**.ts # create performance profile
$ perf script | stackcollapse-perf | c++filt | flamegraph > flame.svg # generate flamegraph
You can use rust-unmangle or rustfilt instead of c++filt.
These commands can take a few minutes to run.
If you are going to work on an issue, mention so in the issue comments before you start working on the issue.
Please be professional in the forums. We follow Rust's code of conduct (CoC) Have a problem? Email ry@tinyclouds.org.
Ask for help in the community chat room.
Before submitting, please make sure the following is done:
cargo test
passes.deno run --allow-run tools/format.ts
deno run --allow-run tools/lint.ts
passes.Visit https://lint.deno.land for the list of available rules.
See the roadmap
Author: Denoland
Source Code: https://github.com/denoland/deno_lint
License: MIT license