From 1d2f71367329aa672acb20f01ebd5ae6a66dcd63 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 5 May 2025 21:01:23 +0400 Subject: [PATCH] Fix Cursor rules files. --- .cursor/rules/api_usage.mdc | 23 ++++++++++++++--------- .cursor/rules/localization.mdc | 7 ++++++- .cursor/rules/rpl_guide.mdc | 31 ++++++++++++++++++------------- .cursor/rules/styling.mdc | 7 ++++++- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/.cursor/rules/api_usage.mdc b/.cursor/rules/api_usage.mdc index c551f0b7ce..bf6e55bbdd 100644 --- a/.cursor/rules/api_usage.mdc +++ b/.cursor/rules/api_usage.mdc @@ -1,8 +1,13 @@ +--- +description: For tasks requiring sending Telegram server API requests or working with generated API types. +globs: +alwaysApply: false +--- # Telegram Desktop API Usage ## API Schema -The API definitions are described using [TL Language](https://core.telegram.org/mtproto/TL) in two main schema files: +The API definitions are described using [TL Language]\(https:/core.telegram.org/mtproto/TL) in two main schema files: 1. **`Telegram/SourceFiles/mtproto/scheme/mtproto.tl`** * Defines the core MTProto protocol types and methods used for basic communication, encryption, authorization, service messages, etc. @@ -39,7 +44,7 @@ api().request(MTPnamespace_MethodName( MTP_long(randomId), // ... other arguments matching the TL definition MTP_vector() // Example for a vector argument -)).done([=](const MTPResponseType &result) { +)).done([=]\(const MTPResponseType &result) { // Handle the successful response (result). // 'result' will be of the C++ type corresponding to the TL type // specified after the '=' in the api.tl method definition. @@ -47,9 +52,9 @@ api().request(MTPnamespace_MethodName( // 1. Multiple Constructors (e.g., User = User | UserEmpty): // Use .match() with lambdas for each constructor: - result.match([&](const MTPDuser &data) { + result.match([&]\(const MTPDuser &data) { /* use data.vfirst_name().v, etc. */ - }, [&](const MTPDuserEmpty &data) { + }, [&]\(const MTPDuserEmpty &data) { /* handle empty user */ }); @@ -64,7 +69,7 @@ api().request(MTPnamespace_MethodName( // 2. Single Constructor (e.g., Messages = messages { msgs: vector }): // Use .match() with a single lambda: - result.match([&](const MTPDmessages &data) { /* use data.vmessages().v */ }); + result.match([&]\(const MTPDmessages &data) { /* use data.vmessages().v */ }); // Or check the type explicitly and use the constructor getter: if (result.type() == mtpc_messages) { @@ -76,7 +81,7 @@ api().request(MTPnamespace_MethodName( const auto &data = result.data(); // Only works for single-constructor types! // use data.vmessages().v -}).fail([=](const MTP::Error &error) { +}).fail([=]\(const MTP::Error &error) { // Handle the API error (error). // 'error' is an MTP::Error object containing the error code (error.type()) // and description (error.description()). Check for specific error strings. @@ -93,8 +98,8 @@ api().request(MTPnamespace_MethodName( * Always refer to `Telegram/SourceFiles/mtproto/scheme/api.tl` for the correct method names, parameters (names and types), and response types. * Use the generated `MTP...` types/classes for request parameters (e.g., `MTP_int`, `MTP_string`, `MTP_bool`, `MTP_vector`, `MTPInputUser`, etc.) and response handling. * The `.done()` lambda receives the specific C++ `MTP...` type corresponding to the TL return type. - * For types with **multiple constructors** (e.g., `User = User | UserEmpty`), use `result.match([&](const MTPDuser &d){ ... }, [&](const MTPDuserEmpty &d){ ... })` to handle each case, or check `result.type() == mtpc_user` / `mtpc_userEmpty` and call the specific `result.c_user()` / `result.c_userEmpty()` getter (which asserts on type mismatch). - * For types with a **single constructor** (e.g., `Messages = messages{...}`), you can use `result.match([&](const MTPDmessages &d){ ... })` with one lambda, or check `type()` and call `c_messages()`, or use the shortcut `result.data()` to access the fields directly. + * For types with **multiple constructors** (e.g., `User = User | UserEmpty`), use `result.match([&]\(const MTPDuser &d){ ... }, [&]\(const MTPDuserEmpty &d){ ... })` to handle each case, or check `result.type() == mtpc_user` / `mtpc_userEmpty` and call the specific `result.c_user()` / `result.c_userEmpty()` getter (which asserts on type mismatch). + * For types with a **single constructor** (e.g., `Messages = messages{...}`), you can use `result.match([&]\(const MTPDmessages &d){ ... })` with one lambda, or check `type()` and call `c_messages()`, or use the shortcut `result.data()` to access the fields directly. * The `.fail()` lambda receives an `MTP::Error` object. Check `error.type()` against known error strings (often defined as constants or using `u"..."_q` literals). * Directly construct the `MTPnamespace_MethodName(...)` object inside `request()`. -* Include `.handleFloodErrors()` before `.send()` for standard flood wait handling. \ No newline at end of file +* Include `.handleFloodErrors()` before `.send()` for standard flood wait handling. diff --git a/.cursor/rules/localization.mdc b/.cursor/rules/localization.mdc index cf39e7d6fd..85e7a32c7a 100644 --- a/.cursor/rules/localization.mdc +++ b/.cursor/rules/localization.mdc @@ -1,3 +1,8 @@ +--- +description: For tasks requiring changing or adding user facing phrases and text parts. +globs: +alwaysApply: false +--- # Telegram Desktop Localization ## Coding Style Note @@ -156,4 +161,4 @@ auto messageProducer = tr::lng_user_posted_photo( // Type: rpl::producer`, typically by converting an `int` producer using `| tr::to_count()`. * Optional projector function as the last argument modifies the output type and required placeholder types. -* Actual translations are loaded at runtime from the API. \ No newline at end of file +* Actual translations are loaded at runtime from the API. diff --git a/.cursor/rules/rpl_guide.mdc b/.cursor/rules/rpl_guide.mdc index 8ff7be46a5..628a1d7e50 100644 --- a/.cursor/rules/rpl_guide.mdc +++ b/.cursor/rules/rpl_guide.mdc @@ -1,3 +1,8 @@ +--- +description: +globs: +alwaysApply: true +--- # RPL (Reactive Programming Library) Guide ## Coding Style Note @@ -64,7 +69,7 @@ rpl::lifetime lifetime; // Counter is consumed here, use std::move if it's an l-value. std::move( counter -) | rpl::start_with_next([=](int nextValue) { +) | rpl::start_with_next([=]\(int nextValue) { // Process the next integer value emitted by the producer. qDebug() << "Received: " << nextValue; }, lifetime); // Pass the lifetime to manage the subscription. @@ -77,7 +82,7 @@ std::move( auto counter2 = /* ... */; // Type: rpl::producer rpl::lifetime subscriptionLifetime = std::move( counter2 -) | rpl::start_with_next([=](int nextValue) { /* ... */ }); +) | rpl::start_with_next([=]\(int nextValue) { /* ... */ }); // The returned lifetime MUST be stored. If it's discarded immediately, // the subscription stops instantly. // `counter2` is also moved-from here. @@ -93,7 +98,7 @@ rpl::lifetime lifetime; // If it's the only use, std::move(dataStream) would be preferred. rpl::duplicate( dataStream -) | rpl::start_with_error([=](Error &&error) { +) | rpl::start_with_error([=]\(Error &&error) { // Handle the error signaled by the producer. qDebug() << "Error: " << error.text(); }, lifetime); @@ -101,7 +106,7 @@ rpl::duplicate( // Using dataStream again, perhaps duplicated again or moved if last use. rpl::duplicate( dataStream -) | rpl::start_with_done([=]() { +) | rpl::start_with_done([=] { // Execute when the producer signals it's finished emitting values. qDebug() << "Stream finished."; }, lifetime); @@ -110,9 +115,9 @@ rpl::duplicate( std::move( dataStream ) | rpl::start_with_next_error_done( - [=](QString &&value) { /* handle next value */ }, - [=](Error &&error) { /* handle error */ }, - [=]() { /* handle done */ }, + [=]\(QString &&value) { /* handle next value */ }, + [=]\(Error &&error) { /* handle error */ }, + [=] { /* handle done */ }, lifetime); ``` @@ -164,7 +169,7 @@ You can combine multiple producers into one: // The lambda receives unpacked arguments, not the tuple itself. std::move( combined - ) | rpl::start_with_next([=](int count, const QString &text) { + ) | rpl::start_with_next([=]\(int count, const QString &text) { // No need for std::get<0>(latest), etc. qDebug() << "Combined: Count=" << count << ", Text=" << text; }, lifetime); @@ -172,11 +177,11 @@ You can combine multiple producers into one: // This also works with map, filter, etc. std::move( combined - ) | rpl::filter([=](int count, const QString &text) { + ) | rpl::filter([=]\(int count, const QString &text) { return count > 0 && !text.isEmpty(); - }) | rpl::map([=](int count, const QString &text) { + }) | rpl::map([=]\(int count, const QString &text) { return text.repeated(count); - }) | rpl::start_with_next([=](const QString &result) { + }) | rpl::start_with_next([=]\(const QString &result) { qDebug() << "Mapped & Filtered: " << result; }, lifetime); ``` @@ -192,7 +197,7 @@ You can combine multiple producers into one: // Starting the merged producer consumes it. std::move( merged - ) | rpl::start_with_next([=](QString &&value) { + ) | rpl::start_with_next([=]\(QString &&value) { // Receives values from either sourceA or sourceB as they arrive. qDebug() << "Merged value: " << value; }, lifetime); @@ -208,4 +213,4 @@ You can combine multiple producers into one: * Use `rpl::combine` or `rpl::merge` to combine streams. * When starting a chain (`std::move(producer) | rpl::map(...)`), explicitly move the initial producer. * These functions typically duplicate their input producers internally. -* Starting a pipeline consumes the producer; use ` \ No newline at end of file +* Starting a pipeline consumes the producer; use ` diff --git a/.cursor/rules/styling.mdc b/.cursor/rules/styling.mdc index 8e3578068f..42729f096c 100644 --- a/.cursor/rules/styling.mdc +++ b/.cursor/rules/styling.mdc @@ -1,3 +1,8 @@ +--- +description: For tasks requiring working with user facing UI components. +globs: +alwaysApply: false +--- # Telegram Desktop UI Styling ## Style Definition Files @@ -146,4 +151,4 @@ void MyWidget::paintEvent(QPaintEvent *e) { * Icons are defined inline using `name: icon{{ "path_stem", color }};` or `name: icon{ { "path1", c1 }, ... };` syntax, with optional path modifiers. * Code generation creates `struct` definitions in the `style` namespace for custom types and objects/structs in the `st` namespace for defined variables/groups. * Generated headers are in `styles/` with a `style_` prefix and must be included. -* Access style properties via the generated `st::` objects (e.g., `st::primaryButton.height`, `st::chatInput.backgroundColor`). \ No newline at end of file +* Access style properties via the generated `st::` objects (e.g., `st::primaryButton.height`, `st::chatInput.backgroundColor`).