├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── changelog.yml │ ├── checks.yml │ ├── deploy.yml │ ├── gen_preview.yml │ ├── pr-preview.yml │ └── release.yml ├── .gitignore ├── .nuxtrc ├── CONTRIBUTING.md ├── CONTRIBUTING_EN.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── README_EN.md ├── app.vue ├── bun.lockb ├── cliff.toml ├── components ├── Button.vue ├── Card.vue ├── CustomConnectionLine.vue ├── Header.vue ├── NodeCard.vue ├── NodeTopics.vue ├── NodeTransparent.vue ├── Roadmap.vue └── sidebar │ └── ReadStatus.vue ├── content ├── 1.introduction │ ├── 0.index.md │ ├── 1.why-rust.md │ ├── 2.rust-channels.md │ ├── 3.environment.yml │ ├── 4.install-rust.md │ ├── 5.code-editor.md │ └── 6.first-program.md ├── 2.basic │ ├── 0.index.md │ ├── 1.syntax.yml │ ├── 10.transfer-ownership.md │ ├── 11.reference-and-mutability.md │ ├── 12.lifetimes.md │ ├── 13.temporary-borrow.md │ ├── 14.primitive-types.yml │ ├── 15.boolean.md │ ├── 16.float.md │ ├── 17.char.md │ ├── 18.signed-integer.md │ ├── 19.unsigned-integer.md │ ├── 2.variables.md │ ├── 20.str.md │ ├── 21.complex-types.yml │ ├── 22.tuples.md │ ├── 23.array.md │ ├── 24.slices.md │ ├── 25.struct.md │ ├── 26.enum.md │ ├── 27.string.md │ ├── 28.range.md │ ├── 29.vector.md │ ├── 3.const-and-statics.md │ ├── 30.hashmap.md │ ├── 4.shadowing.md │ ├── 5.control-flow.md │ ├── 6.function-clousures.md │ ├── 7.pattern-matching.md │ ├── 8.ownership-borrowing.yml │ └── 9.ownership-borrowing-concept.md ├── 3.error-handling │ ├── 1.option.md │ ├── 2.result.md │ ├── 3.propagation-operator.md │ ├── 4.custom-errors.md │ └── index.yml ├── 4.cargo │ ├── 1.format.md │ ├── 2.modules.md │ ├── 3.workspaces.md │ └── index.md ├── 5.traits │ ├── 1.definition.md │ ├── 2.autotraits.md │ ├── 3.integrated.md │ ├── generics.md │ └── index.md ├── 6.smart-pointers │ └── index.md ├── 7.concurrency │ └── index.md ├── 8.interop │ └── index.md ├── 9.ecosystem │ └── index.md ├── continue.yml └── rust.yml ├── crates └── preview │ ├── .gitignore │ ├── Cargo.toml │ ├── assets │ ├── WorkSans-Bold.ttf │ ├── WorkSans-Regular.ttf │ └── bg_preview.png │ └── src │ ├── img.rs │ ├── main.rs │ └── mdx.rs ├── flake.lock ├── flake.nix ├── generateContentRoutes.js ├── index.vue ├── layouts └── hero.vue ├── nuxt.config.ts ├── package.json ├── pages └── [...slug].vue ├── plugins └── locally.js ├── public ├── favicon.ico └── previews │ ├── basic-array.png │ ├── basic-boolean.png │ ├── basic-char.png │ ├── basic-const-and-statics.png │ ├── basic-control-flow.png │ ├── basic-enum.png │ ├── basic-float.png │ ├── basic-function-clousures.png │ ├── basic-hashmap.png │ ├── basic-index.png │ ├── basic-lifetimes.png │ ├── basic-ownership-borrowing-concept.png │ ├── basic-pattern-matching.png │ ├── basic-range.png │ ├── basic-reference-and-mutability.png │ ├── basic-shadowing.png │ ├── basic-signed-integer.png │ ├── basic-slices.png │ ├── basic-str.png │ ├── basic-string.png │ ├── basic-struct.png │ ├── basic-temporary-borrow.png │ ├── basic-transfer-ownership.png │ ├── basic-tuples.png │ ├── basic-unsigned-integer.png │ ├── basic-variables.png │ ├── basic-vector.png │ ├── cargo.png │ ├── concurrency.png │ ├── ecosystem.png │ ├── error-handling.png │ ├── interop.png │ ├── introduction-code-editor.png │ ├── introduction-first-program.png │ ├── introduction-index.png │ ├── introduction-install-rust.png │ ├── introduction-rust-channels.png │ ├── introduction-why-rust.png │ ├── ogpreview.png │ ├── smart-pointers.png │ └── traits.png ├── release.toml ├── rust-toolchain.toml ├── sc.toml ├── server ├── routes │ └── sitemap.xml.ts └── tsconfig.json ├── tailwind.config.js ├── tsconfig.json ├── types └── roadmapSidebar.ts └── wrangler.toml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: SergioRibera 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. NixOS 24.05 (Uakari)] 28 | - Wrangler Version [e.g. 3.28.3] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "pnpm" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | commit-message: 9 | prefix: "chore" 10 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | name: Generate CHANGELOG 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | plan: 7 | required: true 8 | type: string 9 | 10 | jobs: 11 | changelog: 12 | name: Generate changelog 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Generate a changelog 21 | uses: orhun/git-cliff-action@v3 22 | with: 23 | config: cliff.toml 24 | args: -vv --latest 25 | env: 26 | OUTPUT: CHANGELOG.md 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | GITHUB_REPO: ${{ github.repository }} 29 | -------------------------------------------------------------------------------- /.github/workflows/checks.yml: -------------------------------------------------------------------------------- 1 | name: Check Format and Code Quality 2 | on: 3 | workflow_dispatch: 4 | workflow_call: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | - dev 10 | 11 | jobs: 12 | checks: 13 | runs-on: ubuntu-22.04 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Setup Biome CLI 18 | uses: biomejs/setup-biome@v2 19 | - name: checks 20 | run: biome check . 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to production 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - ".github/workflows/deploy.yml" 10 | - "package.json" 11 | - "tsconfig.json" 12 | - "nuxt.config.ts" 13 | - "tailwind.config.js" 14 | - "app.vue" 15 | - "components/**" 16 | - "content/**" 17 | - "public/**" 18 | - "layouts/**" 19 | - "server/**" 20 | 21 | jobs: 22 | deploy: 23 | runs-on: ubuntu-22.04 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v4 27 | - uses: oven-sh/setup-bun@v1 28 | - name: Install Deps 29 | run: bun install 30 | 31 | - name: Build 32 | run: bunx nuxi build --preset=cloudflare_pages 33 | 34 | - name: Deploy 35 | uses: cloudflare/wrangler-action@v3 36 | # env: 37 | # YOUR_SECRET: ${{ secrets.YOUR_SECRET }} 38 | # YOUR_OTHER_SECRET: ${{ secrets.YOUR_OTHER_SECRET }} 39 | with: 40 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} 41 | accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 42 | command: pages deploy ./dist --project-name roadmap 43 | # secrets: | 44 | # YOUR_SECRET 45 | # YOUR_OTHER_SECRET 46 | -------------------------------------------------------------------------------- /.github/workflows/gen_preview.yml: -------------------------------------------------------------------------------- 1 | name: Generate Image Preview 2 | on: 3 | pull_request: 4 | types: 5 | - opened 6 | - synchronize 7 | paths: 8 | - 'content/**' 9 | 10 | # cancel in-progress runs on new commits to same PR (github.event.number) 11 | concurrency: 12 | group: gen_preview_image${{ github.workflow }}-${{ github.event.number || github.sha }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | generate-preview: 17 | runs-on: ubuntu-latest 18 | name: Generate Preview Image 19 | permissions: # Job-level permissions configuration starts here 20 | contents: write # 'write' access to repository contents 21 | pull-requests: write # 'write' access to pull requests 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token. 26 | fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. 27 | # Download bin of gen_preview 28 | - name: Install preview bin 29 | run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/RustLangES/rustmap/releases/download/v0.2.0/preview-installer.sh | sh 30 | 31 | - name: Get changed files 32 | run: | 33 | files=$(git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD main)) 34 | preview ./crates/preview/assets/bg_preview.png ./public/previews $files 35 | - name: Commit changes 36 | run: | 37 | git config --global user.name 'github-actions[bot]' 38 | git config --global user.email 'github-actions[bot]@users.noreply.github.com' 39 | git add -A 40 | git commit -m "chore: generate opengraph image" || echo "No changes to commit" 41 | 42 | - uses: ad-m/github-push-action@master 43 | with: 44 | branch: ${{ github.head_ref }} 45 | 46 | -------------------------------------------------------------------------------- /.github/workflows/pr-preview.yml: -------------------------------------------------------------------------------- 1 | #################### 🚧 WARNING: READ THIS BEFORE USING THIS FILE 🚧 #################### 2 | # 3 | # 4 | # 5 | # IF YOU DON'T KNOW WHAT YOU'RE DOING, YOU CAN EASILY LEAK SECRETS BY USING A 6 | # `pull_request_target` WORKFLOW INSTEAD OF `pull_request`! SERIOUSLY, DO NOT 7 | # BLINDLY COPY AND PASTE THIS FILE WITHOUT UNDERSTANDING THE FULL IMPLICATIONS 8 | # OF WHAT YOU'RE DOING! WE HAVE TESTED THIS FOR OUR OWN USE CASES, WHICH ARE 9 | # NOT NECESSARILY THE SAME AS YOURS! WHILE WE AREN'T EXPOSING ANY OF OUR SECRETS, 10 | # ONE COULD EASILY DO SO BY MODIFYING OR ADDING A STEP TO THIS WORKFLOW! 11 | # 12 | # 13 | # 14 | #################### 🚧 WARNING: READ THIS BEFORE USING THIS FILE 🚧 #################### 15 | 16 | name: Preview Deployment 17 | on: 18 | pull_request_target: 19 | types: 20 | - opened 21 | - synchronize 22 | - closed 23 | 24 | # cancel in-progress runs on new commits to same PR (github.event.number) 25 | concurrency: 26 | group: ${{ github.workflow }}-${{ github.event.number || github.sha }} 27 | cancel-in-progress: true 28 | 29 | jobs: 30 | deploy-preview: 31 | if: ${{ github.event.action != 'closed' }} 32 | permissions: 33 | contents: read 34 | pull-requests: write 35 | deployments: write 36 | runs-on: ubuntu-latest 37 | name: Deploy Preview to Cloudflare Pages 38 | env: 39 | BRANCH_NAME: preview-${{ github.head_ref }} 40 | ACTION_RUN: ${{github.server_url}}/${{github.repository}}/actions/runs/${{github.run_id}} 41 | steps: 42 | - uses: actions/checkout@v4 43 | with: 44 | submodules: "recursive" 45 | ref: ${{ github.event.pull_request.head.ref }} 46 | repository: ${{ github.event.pull_request.head.repo.full_name }} 47 | 48 | - name: Create comment 49 | id: comment 50 | uses: peter-evans/create-or-update-comment@v4 51 | with: 52 | issue-number: ${{ github.event.pull_request.number }} 53 | comment-author: 'github-actions[bot]' 54 | body: | 55 | ## ⚡ Cloudflare Pages Deployment 56 | | Name | Status | Preview | 57 | | :--- | :----- | :------ | 58 | | ${{env.BRANCH_NAME}} | 🔨 Building ([Logs](${{env.ACTION_RUN}})) | waiting... | 59 | 60 | # Build Rust Page 61 | - uses: oven-sh/setup-bun@v1 62 | - name: Install Deps 63 | run: bun install 64 | - name: Build 65 | run: bun run build --preset=cloudflare_pages 66 | 67 | # Deploy steps 68 | - name: Deploy 69 | id: deploy 70 | uses: cloudflare/wrangler-action@v3 71 | with: 72 | apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} 73 | accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 74 | command: pages deploy ./dist --project-name roadmap --branch "${{ env.BRANCH_NAME }}" 75 | 76 | - name: Extract hash from CF url Deploy 77 | run: | 78 | url_hash=$(echo "${{ steps.deploy.outputs.deployment-url }}" | sed -n 's|https://\([^.]*\).roadmap.*|\1|p') 79 | echo "SHA_SHORT=$url_hash" >> $GITHUB_ENV 80 | 81 | - name: Create comment 82 | uses: peter-evans/create-or-update-comment@v4 83 | with: 84 | issue-number: ${{ github.event.pull_request.number }} 85 | comment-id: ${{ steps.comment.outputs.comment-id }} 86 | edit-mode: replace 87 | body: | 88 | ## ⚡ Cloudflare Pages Deployment 89 | | Name | Status | Preview | 90 | | :--- | :----- | :------ | 91 | | ${{env.BRANCH_NAME}} | ✅ Ready ([Logs](${{env.ACTION_RUN}})) | [${{env.SHA_SHORT}}](${{ steps.deploy.outputs.deployment-url }}) | 92 | 93 | # remove-preview: 94 | # if: ${{ github.event.action == "closed" }} 95 | # permissions: 96 | # contents: read 97 | # pull-requests: write 98 | # deployments: write 99 | # runs-on: ubuntu-latest 100 | # name: Remove Preview of Cloudflare Pages 101 | # steps: 102 | # - uses: actions/checkout@v3 103 | # with: 104 | # submodules: "recursive" 105 | # ref: ${{ github.event.pull_request.head.ref }} 106 | # repository: ${{ github.event.pull_request.head.repo.full_name }} 107 | 108 | # - name: Deploy 109 | # id: deploy 110 | # uses: cloudflare/wrangler-action@v3 111 | # with: 112 | # apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} 113 | # accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} 114 | # command: pages --project-name=homepage --branch="${ env.BRANCH_NAME }" 115 | 116 | # - name: Create comment 117 | # uses: peter-evans/create-or-update-comment@v4 118 | # with: 119 | # issue-number: ${{ github.event.pull_request.number }} 120 | # comment-author: 'github-actions[bot]' 121 | # body: | 122 | # ## ⚡ Removing Cloudflare Pages Preview 123 | # | Name | Status | 124 | # | :--- | :----- | 125 | # | ${{env.BRANCH_NAME}} | ✅ Removed | 126 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .wrangler 3 | .output 4 | .data 5 | .nuxt 6 | .nitro 7 | .cache 8 | dist 9 | 10 | # Node dependencies 11 | node_modules 12 | 13 | # Logs 14 | logs 15 | *.log 16 | 17 | # Misc 18 | .DS_Store 19 | .fleet 20 | .idea 21 | 22 | # Local env files 23 | .env 24 | .env.* 25 | !.env.example 26 | 27 | 28 | # Added by cargo 29 | 30 | /target 31 | -------------------------------------------------------------------------------- /.nuxtrc: -------------------------------------------------------------------------------- 1 | telemetry.enabled=false 2 | telemetry.consent=0 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribuyendo al LeetCode Daily Challenge Worker 2 | 3 | ¡Gracias por tu interés en contribuir a este proyecto! A continuación, se detallan las pautas para contribuir de manera efectiva. 4 | 5 | ## Código de Conducta 6 | 7 | Al participar en este proyecto, se espera que sigas nuestro [Código de Conducta](LINK_AL_CODIGO_DE_CONDUCTA). Por favor, léelo y respétalo en todas tus interacciones. 8 | 9 | ## Problemas 10 | 11 | Si encuentras un problema o tienes una sugerencia para mejorar el proyecto, puedes abrir un nuevo issue en el repositorio. Por favor, proporciona detalles claros y concisos sobre el problema o la sugerencia. 12 | 13 | ## Solicitudes de Extracción (Pull Requests) 14 | 15 | 1. Realiza un fork del repositorio y crea una nueva rama para tus cambios. 16 | 2. Realiza tus modificaciones y asegúrate de que el código siga las pautas de estilo y las pruebas pasen. 17 | 3. Escribe pruebas para tu código nuevo o actualizado. 18 | 4. Actualiza la documentación si es necesario. 19 | 5. Crea una solicitud de extracción desde tu rama hacia la rama principal del repositorio original. 20 | 6. Proporciona una descripción clara y concisa de tus cambios. 21 | 7. Asegúrate de que tu solicitud de extracción pase todas las pruebas y revisiones de código requeridas. 22 | 23 | ## Estilo de Código 24 | 25 | Este proyecto sigue las pautas de estilo de código de Rust. Por favor, asegúrate de que tus contribuciones cumplan con estas pautas. 26 | 27 | ## Estructura del contenido 28 | Las carpetas llevan la siguiente estructura dentro de `content/`: 29 | 30 | Las carpeta llevan un orden especificado en el nombre de la carpeta o archivo, antes de un punto, ejemplo `1.slug-name`. 31 | En el archivo `index.md` se define el comportamiento de la carpeta en los nodos. 32 | Todos los datos y metadatos que necesitan para ser parte del seo y el procesamiento van dentro de la seccion de Front-Matter del Markdown y en formato yaml. 33 | 34 | ## Pruebas 35 | 36 | Todas las contribuciones deben incluir pruebas para garantizar la calidad del código. Asegúrate de que tus pruebas cubran los casos de uso relevantes y de que pasen antes de enviar una solicitud de extracción. 37 | 38 | ## Documentación 39 | 40 | Si tu contribución implica cambios en la documentación, por favor, actualízala acorde a tus cambios. Mantener una documentación clara y actualizada es fundamental para la comprensión y el mantenimiento del proyecto. 41 | 42 | ## Licencia 43 | 44 | Al contribuir a este proyecto, aceptas que tus contribuciones se licencien bajo la [LICENCIA MIT](./LICENSE-MIT) del proyecto. 45 | 46 | ¡Gracias por tu interés en contribuir a este proyecto! Esperamos con ansias tus contribuciones. 47 | -------------------------------------------------------------------------------- /CONTRIBUTING_EN.md: -------------------------------------------------------------------------------- 1 | # Contributing to the LeetCode Daily Challenge Worker 2 | 3 | Thank you for your interest in contributing to this project! Below are the guidelines for contributing effectively. 4 | 5 | ## Code of Conduct 6 | 7 | When participating in this project, it is expected that you follow our [Code of Conduct](LINK_TO_CODE_OF_CONDUCT). Please read it and respect it in all your interactions. 8 | 9 | ## Issues 10 | 11 | If you find a bug or have a suggestion to improve the project, you can open a new issue in the repository. Please provide clear and concise details about the problem or suggestion. 12 | 13 | ## Pull Requests (PRs) 14 | 15 | 1. Fork the repository and create a new branch for your changes. 16 | 2. Make your modifications and ensure that the code follows style guidelines and all tests pass. 17 | 3. Write tests for your new or updated code. 18 | 4. Update the documentation if necessary. 19 | 5. Create a pull request from your branch to the main branch of the original repository. 20 | 6. Provide a clear and concise description of your changes. 21 | 7. Ensure that your pull request passes all required tests and code reviews. 22 | 23 | ## Code Style 24 | 25 | This project follows Rust's code style guidelines. Please ensure that your contributions adhere to these guidelines. 26 | 27 | ## Tests 28 | 29 | All contributions must include tests to ensure code quality. Make sure your tests cover relevant use cases and pass before submitting a pull request. 30 | 31 | ## Documentation 32 | 33 | If your contribution involves changes to the documentation, please update it accordingly. Keeping documentation clear and up-to-date is crucial for understanding and maintaining the project. 34 | 35 | ## License 36 | 37 | By contributing to this project, you agree that your contributions will be licensed under the [MIT LICENSE](./LICENSE-MIT) of the project. 38 | 39 | Thank you for your interest in contributing to this project! We look forward to your contributions. 40 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace.package] 2 | name = "rustmap" 3 | version = "0.2.0" 4 | edition = "2021" 5 | repository = "https://github.com/RustLangES/rustmap" 6 | 7 | # Config for 'cargo dist' 8 | [workspace.metadata.dist] 9 | # The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax) 10 | cargo-dist-version = "0.11.1" 11 | # CI backends to support 12 | ci = ["github"] 13 | # The installers to generate for each app 14 | installers = ["shell"] 15 | # Target platforms to build apps for (Rust target-triple syntax) 16 | targets = ["x86_64-unknown-linux-gnu"] 17 | # Host jobs to run in CI 18 | host-jobs = ["./changelog"] 19 | # Publish jobs to run in CI 20 | pr-run-mode = "plan" 21 | 22 | # The profile that 'cargo dist' will build with 23 | [profile.dist] 24 | inherits = "release" 25 | lto = "thin" 26 | 27 | [workspace] 28 | members = ["crates/preview"] 29 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 RustLang en Español 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 |
2 | EN 3 |
4 | 5 | # Ruta de Aprendizaje de Rust en Español 6 | Esta es la ruta de Aprendizaje de Rust hecho por la comunidad de [RustLangES](https://rustlang-es.org) 7 | 8 | ## Setup 9 | 10 | ```bash 11 | # bun 12 | bun install 13 | ``` 14 | 15 | ## Development Server 16 | 17 | ```bash 18 | # bun 19 | bun run dev 20 | ``` 21 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 |
2 | ES 3 |
4 | 5 | # Rust Learning Path in English 6 | This is the Rust Learning Path made by the [RustLangES](https://rustlang-es.org) community 7 | 8 | ## Setup 9 | 10 | ```bash 11 | # bun 12 | bun install 13 | ``` 14 | 15 | ## Development Server 16 | 17 | ```bash 18 | # bun 19 | bun run dev 20 | ``` 21 | -------------------------------------------------------------------------------- /app.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/bun.lockb -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | # https://git-cliff.org/docs/configuration 2 | [changelog] 3 | header = "" 4 | # template for the changelog body 5 | # https://keats.github.io/tera/docs/#introduction 6 | body = """ 7 | {% if version %}\ 8 | ## New Version [{{ version | trim_start_matches(pat="v") }}] 9 | {% else %}\ 10 | ## [UNRELEASED] 11 | {% endif %}\ 12 | {% for group, commits in commits | group_by(attribute="group") %} 13 | ### {{ group | striptags | trim | upper_first }} 14 | {% for commit in commits %} 15 | - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ 16 | {% if commit.breaking %}[**breaking**] {% endif %}\ 17 | {{ commit.message | upper_first }} ({% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\ 18 | {% if commit.github.pr_number %} in #{{ commit.github.pr_number }}{%- endif %}) 19 | {% endfor %} 20 | {% endfor %}\n 21 | """ 22 | footer = """ 23 | {% for release in releases -%} 24 | {% if release.version %}\ 25 | ## [{{ release.version | trim_start_matches(pat="v") }}] 26 | {% else %}\ 27 | ## [UNRELEASED] 28 | {% endif %}\ 29 | {% for group, commits in commits | group_by(attribute="group") %} 30 | ### {{ group | striptags | trim | upper_first }} 31 | {% for commit in commits %} 32 | - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ 33 | {% if commit.breaking %}[**breaking**] {% endif %}\ 34 | {{ commit.message | upper_first }} ({% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\ 35 | {% if commit.github.pr_number %} in #{{ commit.github.pr_number }}{%- endif %}) 36 | {% endfor %} 37 | {% endfor %}\n 38 | {% endfor %} 39 | """ 40 | trim = true 41 | 42 | [git] 43 | # parse the commits based on https://www.conventionalcommits.org 44 | conventional_commits = true 45 | # filter out the commits that are not conventional 46 | filter_unconventional = true 47 | split_commits = false 48 | # sort the commits inside sections by oldest/newest order 49 | sort_commits = "newest" 50 | commit_parsers = [ 51 | { message = "^feat", group = "🚀 Features" }, 52 | { message = "^fix", group = "🐛 Bug Fixes" }, 53 | { message = "^doc", group = "📚 Documentation" }, 54 | { message = "^perf", group = "⚡ Performance" }, 55 | { message = "^refactor", group = "🚜 Refactor" }, 56 | { message = "^style", group = "🎨 Styling" }, 57 | { message = "^test", group = "🧪 Testing" }, 58 | { message = "^chore\\(release\\): prepare for", skip = true }, 59 | { message = "^chore\\(deps.*\\)", skip = true }, 60 | { message = "^chore\\(pr\\)", skip = true }, 61 | { message = "^chore\\(pull\\)", skip = true }, 62 | { message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" }, 63 | { body = ".*security", group = "🛡️ Security" }, 64 | { message = "^revert", group = "◀️ Revert" }, 65 | ] 66 | -------------------------------------------------------------------------------- /components/Button.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /components/Card.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 29 | -------------------------------------------------------------------------------- /components/CustomConnectionLine.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | -------------------------------------------------------------------------------- /components/Header.vue: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /components/NodeCard.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 73 | 74 | 80 | -------------------------------------------------------------------------------- /components/NodeTopics.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 37 | 38 | 44 | -------------------------------------------------------------------------------- /components/NodeTransparent.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 35 | -------------------------------------------------------------------------------- /components/Roadmap.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 71 | 72 | 156 | -------------------------------------------------------------------------------- /components/sidebar/ReadStatus.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 53 | 54 | 79 | -------------------------------------------------------------------------------- /content/1.introduction/0.index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Introducción a Rust' 3 | description: 'Introducción a Rust: El Lenguaje del Futuro en Programación de Sistemas' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 320 10 | y: 100 11 | sourcePosition: 12 | rust: 'top' 13 | targetPosition: 14 | basic: 'bottom' 15 | why-rust: 'right' 16 | rust-channels: 'right' 17 | environment: 'right' 18 | externalLinks: 19 | - name: 'Web Oficial' 20 | english: true 21 | link: 'https://rust-lang.org' 22 | - name: 'Hicimos el sitio web de nuestra boda en Angular y Rust' 23 | english: false 24 | link: 'https://blog.rustlang-es.org/articles/hicimos-el-sitio-web-de-nuestra-boda-en-angular-y-rust-pk8' 25 | --- 26 | ## Introducción a Rust: El Lenguaje del Futuro en Programación de Sistemas 27 | 28 | En el vasto universo de los lenguajes de programación, Rust ha emergido como una estrella en ascenso, atrayendo la atención de desarrolladores de todo el mundo por su enfoque único en la seguridad y el rendimiento. Rust no solo promete, sino que cumple con la difícil tarea de ofrecer un control de bajo nivel sin sacrificar la seguridad y la facilidad de uso. En este post, exploraremos qué hace que Rust sea tan especial y por qué deberías considerarlo para tus próximos proyectos. 29 | 30 | ### ¿Qué es Rust? 31 | 32 | Rust es un lenguaje de programación de sistemas que fue desarrollado por Mozilla Research, con su primera versión estable lanzada en 2015. A diferencia de muchos lenguajes modernos que priorizan la productividad y la simplicidad en detrimento de la eficiencia y el control, Rust busca ofrecer lo mejor de ambos mundos. Está diseñado para ser seguro, concurrente y práctico, permitiendo a los desarrolladores escribir código de bajo nivel sin temor a errores comunes como los desbordamientos de búfer y las condiciones de carrera. 33 | 34 | ### Características Clave de Rust 35 | 36 | 1. **Seguridad de Memoria sin Recolección de Basura:** 37 | Una de las características más distintivas de Rust es su enfoque en la seguridad de la memoria. A diferencia de otros lenguajes que utilizan un recolector de basura para gestionar la memoria, Rust emplea un sistema de propiedad y préstamo. Este sistema permite que el compilador gestione la memoria de manera segura y eficiente, previniendo errores comunes como los punteros colgantes y las fugas de memoria. 38 | 39 | 2. **Control y Rendimiento:** 40 | Rust proporciona un control de bajo nivel similar al de C y C++, permitiendo a los desarrolladores optimizar su código para un rendimiento máximo. Esto lo hace ideal para aplicaciones donde el rendimiento es crítico, como los motores de juegos, los sistemas embebidos y las aplicaciones de tiempo real. 41 | 42 | 3. **Concurrencia sin Miedo:** 43 | La concurrencia es uno de los aspectos más complejos y propensos a errores en la programación. Rust aborda este problema con su sistema de tipos y el análisis estático en tiempo de compilación, lo que ayuda a evitar las condiciones de carrera y otros errores de concurrencia. Su modelo de propiedad garantiza que dos hilos no puedan acceder al mismo recurso mutable simultáneamente, asegurando así una concurrencia segura. 44 | 45 | 4. **Ecosistema y Herramientas:** 46 | Rust cuenta con un ecosistema robusto y en constante crecimiento. Herramientas como Cargo, el gestor de paquetes y compilador de Rust, facilitan la gestión de dependencias y la compilación del código. Además, la comunidad de Rust es conocida por ser extremadamente acogedora y activa, lo que hace que aprender y resolver problemas sea más accesible. 47 | 48 | ### ¿Por Qué Elegir Rust? 49 | 50 | 1. **Proyectos Críticos de Alto Rendimiento:** 51 | Si estás trabajando en proyectos donde el rendimiento y la eficiencia son cruciales, como sistemas operativos, navegadores web o motores de juegos, Rust es una excelente opción. Su capacidad para ofrecer un control de bajo nivel sin sacrificar la seguridad lo hace ideal para estos entornos exigentes. 52 | 53 | 2. **Seguridad en Aplicaciones:** 54 | Para aplicaciones donde la seguridad es una prioridad, Rust proporciona una base sólida para prevenir vulnerabilidades comunes. Su sistema de tipos riguroso y su énfasis en la seguridad de la memoria ayudan a evitar errores que pueden ser explotados en ataques de seguridad. 55 | 56 | 3. **Desarrollo Moderno:** 57 | Rust no solo se trata de rendimiento y seguridad; también está diseñado para ser agradable de usar. Su sintaxis moderna y expresiva, junto con herramientas avanzadas, hacen que el desarrollo sea más eficiente y menos propenso a errores. 58 | 59 | ### Conclusión 60 | 61 | Rust está cambiando la forma en que pensamos sobre la programación de sistemas. Su capacidad para ofrecer seguridad y rendimiento sin compromisos lo convierte en una herramienta poderosa para los desarrolladores modernos. Si aún no has explorado Rust, ahora es el momento de sumergirte y descubrir cómo puede transformar tus proyectos. Con una comunidad en crecimiento y un ecosistema robusto, Rust está preparado para ser un pilar en el desarrollo de software del futuro. 62 | -------------------------------------------------------------------------------- /content/1.introduction/2.rust-channels.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Stable, Beta, Nightly. ¿Que es esto?' 3 | description: 'Stable, Beta, Nightly. Los canales de distribucion y versiones de Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 620 10 | y: 140 11 | sourcePosition: 12 | introduction: 'left' 13 | externalLinks: 14 | - name: 'Web Oficial' 15 | english: true 16 | link: 'https://rust-lang.org' 17 | - name: 'Enlace de Referencia' 18 | english: true 19 | link: 'https://rust-lang.github.io/rustup/concepts/channels.html' 20 | --- 21 | ## Stable, Beta, Nightly. ¿Que es esto? 22 | 23 | Rust es conocido por su enfoque en la seguridad, el rendimiento y la confiabilidad, y parte de lo que hace a Rust tan robusto es su cuidadoso ciclo de lanzamiento. Para mantener el equilibrio entre la estabilidad y la innovación, Rust se distribuye a través de tres canales diferentes: Stable, Beta y Nightly. En este post, exploraremos qué significa cada uno de estos canales y cuándo deberías usarlos. 24 | 25 | ### Canal Stable: Seguridad y Confiabilidad 26 | 27 | El canal Stable es la versión más importante de Rust para la mayoría de los desarrolladores. Como su nombre indica, las versiones en este canal son las más estables y han pasado por un riguroso proceso de prueba. Aquí están las características clave del canal Stable: 28 | 29 | - **Lanzamientos Regulares:** Las versiones estables de Rust se lanzan cada seis semanas, lo que proporciona un flujo constante de mejoras y correcciones de errores. 30 | - **Compatibilidad Garantizada:** El canal Stable garantiza la compatibilidad hacia atrás, lo que significa que el código que compila en una versión estable continuará compilando en versiones futuras. 31 | - **Seguridad y Confiabilidad:** Dado que estas versiones han sido exhaustivamente probadas, son ideales para proyectos de producción donde la estabilidad es crucial. 32 | 33 | **Cuándo usar Stable:** Siempre que estés trabajando en un proyecto de producción o necesites asegurarte de que tu código funcione de manera confiable y segura, debes usar el canal Stable. 34 | 35 | ### Canal Beta: Probando lo Nuevo 36 | 37 | El canal Beta de Rust es una vista previa de lo que vendrá en la próxima versión estable. Esta versión se congela dos semanas antes del lanzamiento estable, y se centra en la corrección de errores y la estabilización de nuevas características. 38 | 39 | - **Vista Previa de Nuevas Características:** El canal Beta te permite probar las nuevas características que se incluirán en la próxima versión estable. 40 | - **Corrección de Errores:** Aunque es menos estable que el canal Stable, el canal Beta todavía es bastante fiable y se utiliza para encontrar y corregir errores antes del lanzamiento oficial. 41 | 42 | **Cuándo usar Beta:** Si quieres estar al tanto de las próximas características y contribuir a la detección de errores, usar el canal Beta es una excelente opción. Es ideal para pruebas y para preparar tu código para futuros lanzamientos estables. 43 | 44 | ### Canal Nightly: Innovación y Experimentación 45 | 46 | El canal Nightly es la vanguardia del desarrollo de Rust. Las versiones Nightly se generan cada noche con las últimas características y correcciones de errores que aún no están listas para el canal Beta. 47 | 48 | - **Acceso a Características Experimentales:** El canal Nightly te da acceso a las características más nuevas y experimentales, incluyendo aquellas que aún están en fase de pruebas. 49 | - **Sin Garantías de Estabilidad:** Dado que estas versiones son las menos probadas, pueden contener errores y no se garantiza que sean estables. 50 | 51 | **Cuándo usar Nightly:** Si eres un desarrollador que quiere experimentar con las últimas innovaciones y no te importa lidiar con posibles inestabilidades, el canal Nightly es para ti. Es especialmente útil para contribuyentes de Rust y aquellos que necesitan características específicas que aún no están disponibles en los canales Beta o Stable. 52 | 53 | ### Conclusión 54 | 55 | El sistema de canales de Rust permite a los desarrolladores elegir el equilibrio adecuado entre estabilidad e innovación para sus necesidades específicas. El canal Stable ofrece seguridad y confiabilidad para proyectos de producción, el canal Beta proporciona una vista previa de las próximas características, y el canal Nightly permite a los desarrolladores experimentar con las últimas novedades del lenguaje. 56 | 57 | Al comprender y utilizar estos canales de manera efectiva, puedes maximizar tu productividad y mantener tu códigobase actualizada y segura. ¡Elige el canal que mejor se adapte a tus necesidades y empieza a explorar todo lo que Rust tiene para ofrecer! 58 | -------------------------------------------------------------------------------- /content/1.introduction/3.environment.yml: -------------------------------------------------------------------------------- 1 | title: 'Configura tu Entorno' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: 620 8 | y: 200 9 | width: 320 10 | sourcePosition: 11 | introduction: 'left' 12 | -------------------------------------------------------------------------------- /content/1.introduction/4.install-rust.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Instala Rust' 3 | description: 'Instalación de Rust con Rustup: Una Guía Rápida en pocos minutos' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 620 10 | y: 240 11 | width: 320 12 | externalLinks: 13 | - name: 'Web Oficial de Rustup' 14 | english: true 15 | link: 'https://rustup.rs' 16 | --- 17 | ## Instalación de Rust con Rustup: Una Guía Rápida 18 | 19 | Rust es un lenguaje de programación que ha ganado popularidad rápidamente debido a su enfoque en la seguridad, el rendimiento y la facilidad de uso. Si estás interesado en comenzar a desarrollar con Rust, el primer paso es instalarlo en tu sistema. La forma más recomendada y sencilla de instalar Rust es usando Rustup, una herramienta de línea de comandos para gestionar tus instalaciones de Rust. En este post, te guiaremos a través del proceso de instalación de Rust utilizando Rustup. 20 | 21 | ### ¿Qué es Rustup? 22 | 23 | Rustup es una herramienta de instalación y gestión de Rust que facilita la configuración de múltiples versiones de Rust y la administración de diferentes toolchains (conjuntos de herramientas) en tu sistema. Con Rustup, puedes acceder fácilmente a los canales Stable, Beta y Nightly de Rust y cambiar entre ellos según sea necesario. 24 | 25 | ### Pasos para Instalar Rust con Rustup 26 | 27 | ### Instalación en Windows 28 | 29 | #### 1. Descargar e Instalar Rustup 30 | 31 | 1. Visita [rustup.rs](https://rustup.rs/) en tu navegador. 32 | 2. Haz clic en el enlace de instalación para Windows. Esto descargará un archivo ejecutable `rustup-init.exe`. 33 | 3. Ejecuta el archivo descargado. Aparecerá una ventana de terminal. 34 | 35 | #### 2. Ejecutar el Instalador 36 | 37 | 1. En la ventana de terminal, se te pedirá que confirmes la instalación. Pulsa `1` y luego `Enter` para proceder con la instalación predeterminada. 38 | 2. El instalador configurará Rust y Rustup en tu sistema. 39 | 40 | #### 3. Configurar el Entorno 41 | 42 | El instalador generalmente configura el entorno de manera automática. Para verificar, abre una nueva ventana de terminal (PowerShell o cmd) y ejecuta: 43 | 44 | ```sh 45 | rustc --version 46 | ``` 47 | 48 | Si ves la versión de Rust, la instalación se ha realizado correctamente. 49 | 50 | ### Instalación en Linux 51 | 52 | #### 1. Descargar e Instalar Rustup 53 | 54 | Abre una terminal y ejecuta el siguiente comando: 55 | 56 | ```sh 57 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 58 | ``` 59 | 60 | #### 2. Ejecutar el Instalador 61 | 62 | Sigue las instrucciones en la terminal. Acepta las opciones predeterminadas presionando `Enter`. 63 | 64 | #### 3. Configurar el Entorno 65 | 66 | Añade Rust a tu PATH ejecutando: 67 | 68 | ```sh 69 | source $HOME/.cargo/env 70 | ``` 71 | 72 | También puedes añadir esta línea al final de tu archivo de configuración de shell (`.bashrc`, `.zshrc`, etc.) para que se ejecute automáticamente al abrir una nueva terminal. 73 | 74 | Para verificar la instalación, ejecuta: 75 | 76 | ```sh 77 | rustc --version 78 | ``` 79 | 80 | Si ves la versión de Rust, la instalación ha sido exitosa. 81 | 82 | ### Instalación en macOS 83 | 84 | #### 1. Descargar e Instalar Rustup 85 | 86 | Abre una terminal y ejecuta el siguiente comando: 87 | 88 | ```sh 89 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 90 | ``` 91 | 92 | #### 2. Ejecutar el Instalador 93 | 94 | Sigue las instrucciones en la terminal. Acepta las opciones predeterminadas presionando `Enter`. 95 | 96 | #### 3. Configurar el Entorno 97 | 98 | Añade Rust a tu PATH ejecutando: 99 | 100 | ```sh 101 | source $HOME/.cargo/env 102 | ``` 103 | 104 | Para asegurarte de que este paso se realice automáticamente al abrir una nueva terminal, añade esta línea al final de tu archivo de configuración de shell (`.bash_profile`, `.zshrc`, etc.). 105 | 106 | Para verificar la instalación, ejecuta: 107 | 108 | ```sh 109 | rustc --version 110 | ``` 111 | 112 | Si ves la versión de Rust, la instalación ha sido exitosa. 113 | 114 | 115 | #### 2. Configurar tu Entorno 116 | 117 | Una vez que Rustup haya terminado de instalarse, necesitas asegurarte de que tu entorno de línea de comandos esté configurado para usar Rust. Rustup te indicará agregar la ruta de Rust a tu archivo de configuración de shell (`.bashrc`, `.zshrc`, etc.). Puedes hacerlo manualmente o dejar que Rustup lo haga automáticamente. 118 | 119 | Si decides hacerlo manualmente, añade la siguiente línea al final de tu archivo de configuración de shell: 120 | 121 | ```sh 122 | source $HOME/.cargo/env 123 | ``` 124 | 125 | Después de hacer esto, asegúrate de recargar tu archivo de configuración ejecutando `source ~/.bashrc` o `source ~/.zshrc`, dependiendo de tu shell. 126 | 127 | #### 3. Verificar la Instalación 128 | 129 | Para verificar que Rust se ha instalado correctamente, puedes ejecutar: 130 | 131 | ```sh 132 | rustc --version 133 | ``` 134 | 135 | Este comando debería mostrar la versión de Rust que tienes instalada. Si ves algo similar a `rustc 1.XX.X (XXXXX YYYY-MM-DD)`, ¡felicidades, ya tienes Rust instalado en tu sistema! 136 | 137 | #### 4. Usar los Canales de Rust 138 | 139 | Una de las ventajas de usar Rustup es la facilidad con la que puedes cambiar entre diferentes versiones de Rust. Por defecto, Rustup instala la versión Stable. Sin embargo, puedes instalar y usar las versiones Beta y Nightly fácilmente. 140 | 141 | Para instalar y usar el canal Beta: 142 | 143 | ```sh 144 | rustup install beta 145 | rustup default beta 146 | ``` 147 | 148 | Para instalar y usar el canal Nightly: 149 | 150 | ```sh 151 | rustup install nightly 152 | rustup default nightly 153 | ``` 154 | 155 | Si en algún momento deseas volver al canal Stable, puedes hacerlo con: 156 | 157 | ```sh 158 | rustup default stable 159 | ``` 160 | 161 | #### 5. Actualizar Rust 162 | 163 | Mantener tu instalación de Rust actualizada es fácil con Rustup. Simplemente ejecuta: 164 | 165 | ```sh 166 | rustup update 167 | ``` 168 | 169 | Este comando actualizará Rustup y todos los toolchains instalados a sus versiones más recientes. 170 | 171 | ### Conclusión 172 | 173 | Instalar Rust usando Rustup es un proceso sencillo que te permitirá empezar a desarrollar en Rust rápidamente. Con Rustup, puedes gestionar fácilmente las versiones de Rust y asegurarte de que siempre tienes acceso a las últimas características y mejoras. Ahora que tienes Rust instalado, estás listo para explorar todo lo que este poderoso lenguaje tiene para ofrecer. ¡Feliz codificación! 174 | -------------------------------------------------------------------------------- /content/1.introduction/6.first-program.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Tu Primer Programa' 3 | description: 'Escribiendo Tu Primer Programa en Rust: Una Guía Paso a Paso' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 620 10 | y: 320 11 | width: 320 12 | externalLinks: 13 | - name: '¡Hola, mundo!' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch01-02-hello-world' 16 | - name: '¡Hola, Cargo!' 17 | english: false 18 | link: 'https://book.rustlang-es.org/ch01-03-hello-cargo' 19 | --- 20 | ## Escribiendo Tu Primer Programa en Rust: Una Guía Paso a Paso 21 | 22 | Rust es un lenguaje de programación moderno que se destaca por su seguridad y rendimiento. Si estás listo para dar tus primeros pasos en Rust, esta guía te ayudará a configurar tu entorno y a escribir tu primer programa sencillo. Vamos a crear un proyecto llamado "hola_mundo" utilizando Cargo, la herramienta de gestión de proyectos de Rust. 23 | 24 | ### ¿Qué es Cargo? 25 | 26 | Cargo es la navaja suiza de Rust. Permite gestionar proyectos, probar código, manejar dependencias, y mucho más. Es una herramienta esencial para cualquier desarrollador de Rust. 27 | 28 | ### Paso 1: Crear un Proyecto con Cargo 29 | 30 | Para crear tu primer proyecto con Cargo, abre una terminal y ejecuta el siguiente comando: 31 | 32 | ```sh 33 | cargo new hola_mundo 34 | ``` 35 | 36 | Este comando creará un nuevo directorio y un proyecto llamado "hola_mundo". Cargo generará los archivos necesarios y un directorio para ti. Vamos a explorar lo que ha creado. 37 | 38 | ### Paso 2: Explorar la Estructura del Proyecto 39 | 40 | Navega al directorio del proyecto y lista los archivos: 41 | 42 | ```sh 43 | cd hola_mundo 44 | ls 45 | ``` 46 | 47 | Deberías ver los siguientes elementos: 48 | 49 | - `Cargo.toml`: Archivo de configuración de Cargo. 50 | - `src`: Directorio de código fuente. 51 | - `main.rs`: Archivo principal de Rust que contiene el punto de entrada del programa. 52 | 53 | Cargo también inicializa un nuevo repositorio Git junto con un archivo `.gitignore`. 54 | 55 | ### Paso 3: Entender el Código Generado 56 | 57 | Abre el archivo `src/main.rs` en tu editor de texto favorito. Verás el siguiente código: 58 | 59 | ```rs 60 | fn main() { 61 | println!("Hello, world!"); 62 | } 63 | ``` 64 | 65 | Vamos a desglosar este código línea por línea. 66 | 67 | #### La Función `main` 68 | 69 | ```rs 70 | fn main() { 71 | 72 | } 73 | ``` 74 | 75 | Estas líneas definen una función llamada `main`. La función `main` es especial: siempre es el primer código que se ejecuta en cada programa ejecutable de Rust. Aquí, la primera línea declara una función llamada `main` que no tiene parámetros y no devuelve nada. Si hubiera parámetros, irían dentro de los paréntesis `()`. 76 | 77 | El cuerpo de la función está envuelto en `{}`. Rust requiere llaves alrededor de todos los cuerpos de función. Es buena costumbre colocar la llave de apertura en la misma línea que la declaración de la función, agregando un espacio entre ambos. 78 | 79 | #### El Cuerpo de la Función `main` 80 | 81 | ```rs 82 | println!("Hello, world!"); 83 | ``` 84 | 85 | Esta línea hace todo el trabajo en este pequeño programa: imprime texto en la pantalla. 86 | 87 | `println!` llama a una macro de Rust. Si hubiéramos llamado a una función en su lugar, habríamos ingresado `println` (sin el `!`). Hablaremos de macros en Rust más adelante. Por ahora, solo necesitas saber que usar un `!` significa que estamos llamando a una macro en lugar de una función normal y que las macros no siempre siguen las mismas reglas que las funciones. 88 | 89 | Terminamos la línea con un punto y coma (`;`), lo que indica que esta expresión ha terminado y la siguiente está lista para comenzar. La mayoría de las líneas de código de Rust terminan con un punto y coma. 90 | 91 | ### Paso 4: Ejecutar el Programa 92 | 93 | Ahora que entendemos el código, es hora de ejecutarlo. En la terminal, ejecuta: 94 | 95 | ```sh 96 | cargo run 97 | ``` 98 | 99 | Deberías ver una salida similar a esta: 100 | 101 | ```sh 102 | $ cargo run 103 | Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs 104 | Running `target/debug/hola_mundo` 105 | Hello, world! 106 | ``` 107 | 108 | Si todo funciona correctamente, ¡felicitaciones! Has escrito y ejecutado tu primer programa en Rust. 109 | -------------------------------------------------------------------------------- /content/2.basic/0.index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Aprende lo Básico' 3 | description: '' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -300 10 | y: 300 11 | sourcePosition: 12 | introduction: 'top' 13 | targetPosition: 14 | error-handling: 'bottom' 15 | --- 16 | # Titulo 17 | -------------------------------------------------------------------------------- /content/2.basic/1.syntax.yml: -------------------------------------------------------------------------------- 1 | title: 'Sintaxis Básica' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: -700 8 | y: 200 9 | width: 320 10 | align: 'center' 11 | sourcePosition: 12 | none: 'top' 13 | targetPosition: 14 | basic: 'right' 15 | -------------------------------------------------------------------------------- /content/2.basic/10.transfer-ownership.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Transferencia de Ownership' 3 | description: 'Transferencias de Ownership en Rust: Un Cambio Fundamental en la Gestión de Recursos' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 600 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch04-01-what-is-ownership?highlight=transferencia#valores-de-retorno-y-alcance' 16 | --- 17 | ## Transferencias de Ownership en Rust: Un Cambio Fundamental en la Gestión de Recursos 18 | 19 | ### Introducción 20 | 21 | Rust es un lenguaje de programación que ha capturado la atención de desarrolladores por su enfoque único en la seguridad y el rendimiento. Un aspecto crucial que diferencia a Rust de otros lenguajes es su sistema de **ownership (propiedad)**. La **transferencia de ownership** es una característica clave de este sistema, que permite manejar la memoria de manera segura y eficiente. En este post, exploraremos en detalle cómo funcionan las transferencias de ownership en Rust y por qué son fundamentales para el paradigma de gestión de recursos del lenguaje. 22 | 23 | ### Concepto de Ownership en Rust 24 | 25 | En Rust, cada valor en el programa tiene un único propietario. Esta variable propietaria es responsable de liberar los recursos asociados cuando sale del alcance (scope). Este enfoque asegura que no haya duplicaciones de liberación de memoria ni fugas de memoria, proporcionando una seguridad robusta en tiempo de compilación. 26 | 27 | ### ¿Qué es la Transferencia de Ownership? 28 | 29 | La transferencia de ownership ocurre cuando un valor se mueve de una variable a otra, transfiriendo con ello la responsabilidad de gestionar ese valor. En Rust, esto se conoce como "mover" (move). Una vez que un valor ha sido movido, la variable original ya no puede usarse para acceder al valor, evitando así accesos inválidos a memoria. 30 | 31 | ### Ejemplo de Transferencia de Ownership 32 | 33 | Consideremos el siguiente ejemplo para ilustrar cómo funciona la transferencia de ownership: 34 | 35 | ```rust 36 | fn main() { 37 | let s1 = String::from("Hello"); 38 | let s2 = s1; // s1 se mueve a s2 39 | println!("{}", s2); // Esto funciona 40 | // println!("{}", s1); // Esto causaría un error de compilación 41 | } 42 | ``` 43 | 44 | En este código, la cadena `"Hello"` se asigna a `s1`. Luego, `s1` se mueve a `s2`, transfiriendo la propiedad. Intentar usar `s1` después de la transferencia causará un error de compilación porque `s1` ya no es válido. 45 | 46 | ### Transferencias de Ownership en Funciones 47 | 48 | Las transferencias de ownership también ocurren cuando se pasan parámetros a funciones y cuando se retornan valores desde funciones. Veamos un ejemplo: 49 | 50 | ```rust 51 | fn main() { 52 | let s1 = String::from("Hello"); 53 | takes_ownership(s1); // s1 se mueve a la función 54 | // println!("{}", s1); // Esto causaría un error de compilación 55 | } 56 | 57 | fn takes_ownership(some_string: String) { 58 | println!("{}", some_string); 59 | } 60 | ``` 61 | 62 | En este caso, `s1` se mueve a la función `takes_ownership`, transfiriendo la propiedad. Una vez que `s1` ha sido movido, ya no puede usarse en `main`. 63 | 64 | ### Retorno de Valores y Ownership 65 | 66 | Rust también permite transferir ownership cuando se retorna un valor desde una función: 67 | 68 | ```rust 69 | fn main() { 70 | let s1 = gives_ownership(); 71 | println!("{}", s1); 72 | } 73 | 74 | fn gives_ownership() -> String { 75 | let some_string = String::from("Hello"); 76 | some_string // se mueve al llamador 77 | } 78 | ``` 79 | 80 | Aquí, la función `gives_ownership` crea una cadena y luego la retorna, transfiriendo la propiedad al llamador. 81 | 82 | ### Clonación: Copias en Lugar de Movimientos 83 | 84 | En algunos casos, es posible que desees hacer una copia en lugar de mover un valor. Rust permite esto mediante el método `clone`, que crea una copia profunda del valor: 85 | 86 | ```rust 87 | fn main() { 88 | let s1 = String::from("Hello"); 89 | let s2 = s1.clone(); // Se clona s1 90 | println!("{}", s1); // Esto funciona 91 | println!("{}", s2); // Esto también funciona 92 | } 93 | ``` 94 | 95 | ### Beneficios de la Transferencia de Ownership 96 | 97 | 1. **Seguridad en Tiempo de Compilación:** Al transferir ownership de manera explícita, Rust asegura que no haya accesos inválidos a memoria ni liberaciones duplicadas. 98 | 99 | 2. **Control de Recursos:** La transferencia de ownership proporciona un control preciso sobre la vida útil de los recursos, lo que es crucial para el rendimiento y la eficiencia. 100 | 101 | 3. **Prevención de Errores Comunes:** Errores como las fugas de memoria y las condiciones de carrera se evitan gracias a las reglas de ownership y borrowing. 102 | 103 | ### Conclusión 104 | 105 | La transferencia de ownership es un concepto central en Rust que redefine cómo gestionamos la memoria y los recursos. Al asegurar que cada valor tenga un único propietario y al validar las transferencias de ownership en tiempo de compilación, Rust proporciona un nivel de seguridad y eficiencia que es difícil de alcanzar en otros lenguajes. Aunque puede requerir un cambio de mentalidad para los desarrolladores acostumbrados a otros paradigmas, los beneficios que ofrece en términos de seguridad y control hacen que valga la pena adoptar este enfoque. 106 | -------------------------------------------------------------------------------- /content/2.basic/14.primitive-types.yml: -------------------------------------------------------------------------------- 1 | title: 'Tipos de Datos Primitivos' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: -50 8 | y: 240 9 | width: 320 10 | align: 'left' 11 | sourcePosition: 12 | none: 'top' 13 | targetPosition: 14 | basic: 'left' 15 | -------------------------------------------------------------------------------- /content/2.basic/15.boolean.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'bool' 3 | description: 'El Tipo Booleano en Rust: Características, Operaciones y Usos Prácticos' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -50 10 | y: 280 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types#el-tipo-booleano' 16 | - name: 'Libro de Referencia Rust' 17 | english: true 18 | link: 'https://doc.rust-lang.org/reference/types/boolean.html' 19 | --- 20 | ## El Tipo Booleano en Rust: Características, Operaciones y Usos Prácticos 21 | 22 | El tipo `bool` en Rust representa un valor booleano, que puede ser verdadero (`true`) o falso (`false`). Es uno de los tipos más fundamentales en cualquier lenguaje de programación y se utiliza ampliamente en Rust para controlar el flujo de ejecución y tomar decisiones basadas en condiciones. En este post, exploraremos las características principales del tipo `bool`, su funcionamiento en memoria, y algunos usos prácticos, incluyendo operaciones lógicas y comparaciones. 23 | 24 | ### Características Principales del Tipo `bool` 25 | 26 | 1. **Valores:** El tipo `bool` puede tener solo dos valores: `true` o `false`. 27 | 28 | 2. **Tamaño en Memoria:** En Rust, un valor `bool` ocupa un solo byte en la memoria. Aunque solo necesita un bit para almacenar `true` o `false`, utilizar un byte completo simplifica la alineación en memoria y la manipulación de datos a nivel de hardware. 29 | 30 | 3. **Operaciones Lógicas:** Los valores `bool` se pueden combinar mediante operaciones lógicas como AND (`&&`), OR (`||`), y NOT (`!`). Estas operaciones son fundamentales para la evaluación de expresiones booleanas. 31 | 32 | 4. **Comparaciones:** Los valores `bool` se pueden comparar utilizando los operadores de comparación (`==`, `!=`, `<`, `>`, `<=`, `>=`). Estas comparaciones ayudan a evaluar la igualdad o el orden relativo de los valores booleanos. 33 | 34 | 5. **Uso en Expresiones Condicionales:** Los valores `bool` se utilizan comúnmente en expresiones condicionales como las declaraciones `if`, `while`, y `for` para controlar el flujo de ejecución del programa. 35 | 36 | ### Ejemplos de Uso del Tipo `bool` en Rust 37 | 38 | #### 1. Declaraciones Condicionales 39 | 40 | ```rust 41 | let es_mayor_de_edad = true; 42 | 43 | if es_mayor_de_edad { 44 | println!("Puede comprar alcohol"); 45 | } else { 46 | println!("No puede comprar alcohol"); 47 | } 48 | ``` 49 | 50 | **Gráfico 1: Uso de `bool` en Declaraciones Condicionales** 51 | 52 | ```plaintext 53 | let es_mayor_de_edad = true; 54 | | 55 | v 56 | +------------+ 57 | | true | 58 | +------------+ 59 | | 60 | v 61 | if es_mayor_de_edad { 62 | println!("Puede comprar alcohol"); 63 | } else { 64 | println!("No puede comprar alcohol"); 65 | } 66 | ``` 67 | 68 | #### 2. Operaciones Lógicas 69 | 70 | ```rust 71 | let tiene_licencia = true; 72 | let tiene_coche = false; 73 | 74 | if tiene_licencia && tiene_coche { 75 | println!("Puede conducir"); 76 | } else { 77 | println!("No puede conducir"); 78 | } 79 | ``` 80 | 81 | **Gráfico 2: Operaciones Lógicas con `bool`** 82 | 83 | ```plaintext 84 | let tiene_licencia = true; 85 | let tiene_coche = false; 86 | | | 87 | v v 88 | +------------+ +------------+ 89 | | true | | false | 90 | +------------+ +------------+ 91 | | | 92 | +------AND-------+ 93 | | 94 | v 95 | if tiene_licencia && tiene_coche { 96 | println!("Puede conducir"); 97 | } else { 98 | println!("No puede conducir"); 99 | } 100 | ``` 101 | 102 | #### 3. Comparaciones 103 | 104 | ```rust 105 | let a = true; 106 | let b = false; 107 | 108 | if a != b { 109 | println!("Los valores son diferentes"); 110 | } else { 111 | println!("Los valores son iguales"); 112 | } 113 | ``` 114 | 115 | **Gráfico 3: Comparaciones con `bool`** 116 | 117 | ```plaintext 118 | let a = true; 119 | let b = false; 120 | | | 121 | v v 122 | +------------+ +------------+ 123 | | true | | false | 124 | +------------+ +------------+ 125 | | | 126 | +----!=--+ 127 | | 128 | v 129 | if a != b { 130 | println!("Los valores son diferentes"); 131 | } else { 132 | println!("Los valores son iguales"); 133 | } 134 | ``` 135 | 136 | ### Métodos Más Utilizados 137 | 138 | En Rust, el tipo `bool` es primitivo y no tiene métodos específicos asociados. Sin embargo, se pueden utilizar funciones y métodos proporcionados por Rust para trabajar con valores booleanos. Algunas de las funciones y métodos más comunes son: 139 | 140 | - **true y false:** Valores de tipo `bool`. 141 | 142 | - **not():** Método utilizado para negar un valor booleano. 143 | 144 | - **and():** Método utilizado para realizar una operación lógica AND entre dos valores booleanos. 145 | 146 | - **or():** Método utilizado para realizar una operación lógica OR entre dos valores booleanos. 147 | 148 | #### Ejemplo de Métodos Booleanos 149 | 150 | ```rust 151 | fn main() { 152 | if false.and(true).or(false) { 153 | println!("La expresión es verdadera"); 154 | } else { 155 | println!("La expresión es falsa"); 156 | } 157 | } 158 | ``` 159 | 160 | **Gráfico 4: Métodos Booleanos** 161 | 162 | ```plaintext 163 | false.and(true) --> false 164 | false.or(false) --> false 165 | 166 | if false.and(true).or(false) { 167 | println!("La expresión es verdadera"); 168 | } else { 169 | println!("La expresión es falsa"); 170 | } 171 | ``` 172 | 173 | ### Conclusión 174 | 175 | El tipo `bool` en Rust, aunque simple, es esencial para el control del flujo de ejecución y la toma de decisiones en los programas. Su implementación del trait `Copy` permite copiar valores booleanos de manera eficiente, y su representación en memoria es directa y eficaz. Además, su uso en operaciones lógicas y comparaciones es fundamental para evaluar y combinar condiciones. Comprender y utilizar correctamente el tipo `bool` nos ayuda a escribir código Rust más seguro y eficiente. 176 | -------------------------------------------------------------------------------- /content/2.basic/16.float.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'f32, f64' 3 | description: 'Los Tipos de Punto Flotante `f32` y `f64` en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 24 10 | y: 280 11 | width: 130 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types#tipos-de-punto-flotante' 16 | --- 17 | ## Los Tipos de Punto Flotante `f32` y `f64` en Rust 18 | 19 | En Rust, los tipos `f32` y `f64` son tipos de datos de punto flotante que representan números de coma flotante de precisión simple y doble, respectivamente. Estos tipos son esenciales para realizar cálculos numéricos que requieren decimales, y cada uno tiene sus propias características y usos. En este post, exploraremos las diferencias entre `f32` y `f64`, sus aplicaciones típicas y algunos ejemplos de uso en Rust. 20 | 21 | ### Diferencias entre `f32` y `f64` 22 | 23 | #### 1. Precisión 24 | 25 | La principal diferencia entre `f32` y `f64` es la precisión: 26 | - `f32` utiliza 32 bits para representar un número de coma flotante. 27 | - `f64` utiliza 64 bits para representar un número de coma flotante. 28 | 29 | Debido a esto, `f64` proporciona una mayor precisión y un rango más amplio de valores que `f32`. 30 | 31 | #### 2. Rango de Valores 32 | 33 | - **`f32`:** Tiene un rango de valores aproximado de ±3.40282347e+38 y una precisión de aproximadamente 7 dígitos decimales. 34 | - **`f64`:** Tiene un rango de valores aproximado de ±1.7976931348623157e+308 y una precisión de aproximadamente 15 dígitos decimales. 35 | 36 | #### 3. Rendimiento 37 | 38 | En términos de rendimiento, no existe una diferencia significativa entre `f32` y `f64` en la mayoría de los procesadores modernos, ya que ambos utilizan los mismos algoritmos y métodos de procesamiento. Sin embargo, `f32` puede ser preferible en aplicaciones donde el uso de memoria es una preocupación importante. 39 | 40 | ### Usos de `f32` y `f64` 41 | 42 | - **`f32`:** Se utiliza cuando se requiere una menor precisión y se desea ahorrar memoria, como en gráficos de juegos, cálculos científicos con menos precisión o aplicaciones de bajo consumo de recursos. 43 | - **`f64`:** Se utiliza cuando se requiere una mayor precisión, como en cálculos financieros, ingeniería de precisión o aplicaciones científicas donde se necesitan valores muy precisos. 44 | 45 | ### Ejemplos de Uso en Rust 46 | 47 | ```rust 48 | fn main() { 49 | let x: f32 = 3.14; // Declaración de un valor f32 50 | let y: f64 = 3.14; // Declaración de un valor f64 51 | 52 | println!("Valor de x: {}", x); 53 | println!("Valor de y: {}", y); 54 | 55 | // Operaciones aritméticas 56 | let suma = x as f64 + y; 57 | let resta = x as f64 - y; 58 | let multiplicacion = x as f64 * y; 59 | let division = x as f64 / y; 60 | 61 | println!("Suma: {}", suma); 62 | println!("Resta: {}", resta); 63 | println!("Multiplicación: {}", multiplicacion); 64 | println!("División: {}", division); 65 | } 66 | ``` 67 | 68 | **Gráfico 1: Ejemplo de Operaciones con `f32` y `f64`** 69 | 70 | ```plaintext 71 | let x: f32 = 3.14; // 32-bit float 72 | let y: f64 = 3.14; // 64-bit float 73 | 74 | +-----+ +-------+ 75 | | x |----->| 3.14 | 76 | +-----+ +-------+ 77 | f32 78 | 79 | +-----+ +-------+ 80 | | y |----->| 3.14 | 81 | +-----+ +-------+ 82 | f64 83 | 84 | let suma = x as f64 + y; 85 | let resta = x as f64 - y; 86 | let multiplicacion = x as f64 * y; 87 | let division = x as f64 / y; 88 | ``` 89 | 90 | ### Métodos Más Utilizados 91 | 92 | Los tipos `f32` y `f64` no tienen métodos específicos asociados ya que son tipos primitivos en Rust. Sin embargo, se pueden utilizar funciones y métodos proporcionados por Rust para trabajar con valores de punto flotante. Algunas de las funciones y métodos más comunes son: 93 | 94 | - **`abs()`:** Devuelve el valor absoluto de un número. 95 | - **`ceil()`:** Redondea hacia arriba al número entero más cercano. 96 | - **`floor()`:** Redondea hacia abajo al número entero más cercano. 97 | - **`round()`:** Redondea al número entero más cercano. 98 | - **`sqrt()`:** Calcula la raíz cuadrada del número. 99 | 100 | #### Ejemplo de Uso de Métodos de Punto Flotante 101 | 102 | ```rust 103 | fn main() { 104 | let z: f64 = -3.14; 105 | 106 | println!("Valor absoluto: {}", z.abs()); 107 | println!("Redondeo hacia arriba: {}", z.ceil()); 108 | println!("Redondeo hacia abajo: {}", z.floor()); 109 | println!("Redondeo al entero más cercano: {}", z.round()); 110 | println!("Raíz cuadrada de 9.0: {}", 9.0f64.sqrt()); 111 | } 112 | ``` 113 | 114 | **Gráfico 2: Métodos Comunes para `f32` y `f64`** 115 | 116 | ```plaintext 117 | let z: f64 = -3.14; 118 | 119 | +-----+ +-------+ 120 | | z |----->| -3.14 | 121 | +-----+ +-------+ 122 | f64 123 | 124 | z.abs() -> 3.14 125 | z.ceil() -> -3.0 126 | z.floor() -> -4.0 127 | z.round() -> -3.0 128 | 9.0.sqrt() -> 3.0 129 | ``` 130 | 131 | ### Conclusión 132 | 133 | Los tipos de punto flotante `f32` y `f64` en Rust son esenciales para realizar cálculos numéricos precisos. La elección entre `f32` y `f64` depende de la precisión requerida y las restricciones de memoria de la aplicación. Con una comprensión clara de las diferencias y usos de cada uno, podemos tomar decisiones informadas al escribir código eficiente y preciso en Rust. 134 | -------------------------------------------------------------------------------- /content/2.basic/17.char.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'char' 3 | description: 'El Tipo `char` en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 158 10 | y: 280 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types#el-tipo-de-car%C3%A1cter' 16 | - name: 'Ferrous System' 17 | english: true 18 | link: 'https://github.com/ferrous-systems/rust-training/blob/main/training-slides/src/basic-types.md#character' 19 | --- 20 | ## El Tipo `char` en Rust 21 | 22 | El tipo `char` en Rust representa un solo carácter Unicode, que puede ser un carácter alfabético, numérico, un símbolo o un carácter especial. Este tipo es fundamental para la manipulación de texto en Rust. En este post, detallaremos las características del tipo `char`, sus usos, los métodos más comunes y cómo se maneja en memoria. 23 | 24 | ### Características del Tipo `char` 25 | 26 | #### 1. Representación Unicode 27 | 28 | En Rust, los valores `char` se representan utilizando el estándar Unicode, lo que permite representar caracteres de cualquier lenguaje humano, así como una amplia variedad de símbolos y caracteres especiales. 29 | 30 | #### 2. Tamaño en Memoria 31 | 32 | Los valores `char` en Rust ocupan 4 bytes de memoria. Esto se debe a que están codificados en UTF-8, donde cada carácter Unicode se representa por hasta 4 bytes. Esta capacidad de almacenamiento permite manejar una amplia gama de caracteres Unicode. 33 | 34 | #### 3. Inmutabilidad 35 | 36 | Los valores `char` son inmutables, lo que significa que una vez que se asigna un valor a una variable `char`, este no se puede cambiar. 37 | 38 | ### Usos del Tipo `char` 39 | 40 | - **Representación de Caracteres:** Se utiliza para representar caracteres individuales en texto, como letras, números, símbolos o caracteres especiales. 41 | - **Procesamiento de Texto y Cadenas:** Es útil para manipular y procesar texto en programas, como contar caracteres, extraer subcadenas o realizar operaciones de búsqueda y reemplazo. 42 | 43 | ### Métodos Más Comunes 44 | 45 | Aunque el tipo `char` en Rust no tiene métodos específicos asociados, se pueden realizar operaciones comunes utilizando funciones proporcionadas por Rust para trabajar con caracteres. Algunas de las funciones más comunes son: 46 | 47 | - **`is_alphabetic()`:** Devuelve `true` si el carácter es una letra alfabética. 48 | - **`is_numeric()`:** Devuelve `true` si el carácter es un dígito numérico. 49 | - **`to_uppercase()`:** Convierte el carácter a mayúsculas. 50 | - **`to_lowercase()`:** Convierte el carácter a minúsculas. 51 | - **`is_whitespace()`:** Devuelve `true` si el carácter es un espacio en blanco. 52 | - **`is_ascii()`:** Devuelve `true` si el carácter es un carácter ASCII de 7 bits. 53 | 54 | ### Ejemplo de Uso en Rust 55 | 56 | ```rust 57 | fn main() { 58 | let ch: char = 'a'; 59 | 60 | if ch.is_alphabetic() { 61 | println!("{} es una letra alfabética", ch); 62 | } 63 | 64 | if ch.is_numeric() { 65 | println!("{} es un dígito numérico", ch); 66 | } 67 | 68 | println!("{} en mayúsculas es {}", ch, ch.to_uppercase()); 69 | println!("{} en minúsculas es {}", ch.to_lowercase().next().unwrap(), ch.to_lowercase()); 70 | println!("{} es un espacio en blanco: {}", ch, ch.is_whitespace()); 71 | println!("{} es un carácter ASCII: {}", ch, ch.is_ascii()); 72 | } 73 | ``` 74 | 75 | **Gráfico 1: Ejemplo de Uso del Tipo `char`** 76 | 77 | ```plaintext 78 | let ch: char = 'a'; 79 | 80 | +-----+ +---+ 81 | | ch |----->| a | 82 | +-----+ +---+ 83 | char 84 | 85 | ch.is_alphabetic() -> true 86 | ch.is_numeric() -> false 87 | ch.to_uppercase() -> 'A' 88 | ch.to_lowercase() -> 'a' 89 | ch.is_whitespace() -> false 90 | ch.is_ascii() -> true 91 | ``` 92 | 93 | ### Espacio en Memoria 94 | 95 | Como se mencionó anteriormente, los valores `char` en Rust ocupan 4 bytes de memoria, ya que están codificados en UTF-8. Esto permite representar una amplia gama de caracteres Unicode con un solo valor `char`. La codificación UTF-8 también garantiza una compatibilidad completa con los estándares Unicode y la capacidad de representar texto en múltiples idiomas y scripts. 96 | 97 | **Gráfico 2: Espacio en Memoria del Tipo `char`** 98 | 99 | ```plaintext 100 | +---------------------+ 101 | | 'a' | 102 | | | 103 | | 4 bytes (UTF-8) | 104 | +---------------------+ 105 | ``` 106 | 107 | ### Conclusión 108 | 109 | El tipo `char` en Rust es una herramienta poderosa para manejar caracteres individuales y realizar operaciones de procesamiento de texto. Su representación en Unicode y su capacidad para ocupar 4 bytes de memoria le permiten manejar una amplia gama de caracteres de diferentes idiomas y scripts. Comprender cómo utilizar y manipular el tipo `char` es esencial para escribir programas eficientes y robustos en Rust. 110 | -------------------------------------------------------------------------------- /content/2.basic/18.signed-integer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'i8, i16, i32, i64, i128, isize' 3 | description: 'Comprendiendo los Tipos Enteros con Signo en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -50 10 | y: 320 11 | width: 280 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types.html#tipos-de-enteros' 16 | - name: 'Ferrous System' 17 | english: true 18 | link: 'https://github.com/ferrous-systems/rust-training/blob/main/training-slides/src/basic-types.md#integers' 19 | - name: 'Ferrocene Language Specification' 20 | english: true 21 | link: 'https://public-docs.ferrocene.dev/main/specification/types-and-traits.html#integer-types' 22 | --- 23 | ## Comprendiendo los Tipos Enteros con Signo en Rust 24 | 25 | En Rust, los tipos `i8`, `i16`, `i32`, `i64`, `i128` y `isize` son tipos de datos enteros con signo que representan números enteros con diferentes tamaños y rangos. Estos tipos son fundamentales para el manejo eficiente de números enteros en Rust. A continuación, se presenta una explicación detallada de cada uno, sus usos, métodos comunes y su espacio en memoria. 26 | 27 | ### Tipos Enteros con Signo en Rust 28 | 29 | #### 1. `i8` 30 | - **Descripción:** Representa números enteros con signo de 8 bits. 31 | - **Rango de valores:** -128 a 127. 32 | - **Espacio en memoria:** 1 byte. 33 | 34 | #### 2. `i16` 35 | - **Descripción:** Representa números enteros con signo de 16 bits. 36 | - **Rango de valores:** -32,768 a 32,767. 37 | - **Espacio en memoria:** 2 bytes. 38 | 39 | #### 3. `i32` 40 | - **Descripción:** Representa números enteros con signo de 32 bits. 41 | - **Rango de valores:** -2,147,483,648 a 2,147,483,647. 42 | - **Espacio en memoria:** 4 bytes. 43 | 44 | #### 4. `i64` 45 | - **Descripción:** Representa números enteros con signo de 64 bits. 46 | - **Rango de valores:** -9,223,372,036,854,775,808 a 9,223,372,036,854,775,807. 47 | - **Espacio en memoria:** 8 bytes. 48 | 49 | #### 5. `i128` 50 | - **Descripción:** Representa números enteros con signo de 128 bits. 51 | - **Rango de valores:** -170,141,183,460,469,231,731,687,303,715,884,105,728 a 170,141,183,460,469,231,731,687,303,715,884,105,727. 52 | - **Espacio en memoria:** 16 bytes. 53 | 54 | #### 6. `isize` 55 | - **Descripción:** Representa números enteros con signo que tienen el tamaño de un puntero. Esto significa que su tamaño puede variar dependiendo de la arquitectura del sistema. 56 | - **Rango de valores:** Depende de la arquitectura. 57 | - **Espacio en memoria:** 4 bytes en sistemas de 32 bits, 8 bytes en sistemas de 64 bits. 58 | 59 | ### Usos de los Tipos Enteros con Signo 60 | 61 | - **Almacenamiento de datos:** Se utilizan para almacenar números enteros con signo en diferentes rangos, dependiendo de la precisión requerida por la aplicación. 62 | - **Operaciones aritméticas:** Se utilizan para realizar operaciones matemáticas como suma, resta, multiplicación y división en valores enteros. 63 | - **Índices y tamaños de datos:** `isize` se utiliza comúnmente para índices y tamaños de datos en estructuras de datos, ya que su tamaño se ajusta automáticamente a la arquitectura del sistema. 64 | 65 | ### Métodos Más Comunes 66 | 67 | Los tipos enteros en Rust no tienen métodos específicos asociados, pero se pueden utilizar funciones proporcionadas por Rust para realizar operaciones comunes. Algunas de las funciones más utilizadas son: 68 | 69 | - **`abs()`:** Devuelve el valor absoluto del número. 70 | - **`to_string()`:** Convierte el número en una cadena de caracteres. 71 | - **`overflowing_add()`:** Realiza una suma con desbordamiento silencioso, devolviendo una tupla con el resultado y un indicador de desbordamiento. 72 | - **`wrapping_add()`:** Realiza una suma con desbordamiento modular, devolviendo el resultado con un desbordamiento envuelto. 73 | 74 | ### Ejemplos de Uso en Rust 75 | 76 | ```rust 77 | fn main() { 78 | let a: i32 = -42; 79 | let b: i32 = 56; 80 | 81 | // Operaciones comunes 82 | println!("Valor absoluto de a: {}", a.abs()); 83 | println!("a como cadena: {}", a.to_string()); 84 | println!("Número de bits en 1 en b: {}", b.count_ones()); 85 | println!("Número de bits en 0 en b: {}", b.count_zeros()); 86 | 87 | let (sum, overflowed) = a.overflowing_add(b); 88 | println!("Suma con posible desbordamiento: {} (desbordado: {})", sum, overflowed); 89 | 90 | let wrapped_sum = a.wrapping_add(b); 91 | println!("Suma con desbordamiento envuelto: {}", wrapped_sum); 92 | } 93 | ``` 94 | 95 | **Gráfico 1: Ejemplo de Operaciones Comunes con Enteros en Rust** 96 | 97 | ```rust 98 | let a: i32 = -42; 99 | let b: i32 = 56; 100 | 101 | a.abs(); // -> 42 102 | a.to_string(); // -> "-42" 103 | b.count_ones(); // -> 5 104 | b.count_zeros(); // -> 27 105 | a.overflowing_add(b) // -> (14, false) 106 | a.wrapping_add(b) // -> 14 107 | ``` 108 | 109 | ### Espacio en Memoria 110 | 111 | El espacio en memoria ocupado por los tipos enteros depende del tamaño de cada tipo: 112 | 113 | - **`i8`:** 1 byte 114 | - **`i16`:** 2 bytes 115 | - **`i32`:** 4 bytes 116 | - **`i64`:** 8 bytes 117 | - **`i128`:** 16 bytes 118 | - **`isize`:** 4 bytes en sistemas de 32 bits, 8 bytes en sistemas de 64 bits 119 | 120 | Estos tamaños de memoria son fijos y no dependen de los valores almacenados en las variables. 121 | 122 | **Gráfico 2: Tamaños de Memoria de los Tipos Enteros en Rust** 123 | 124 | ```plaintext 125 | +------+ +------+ 126 | | Tipo | | Size | 127 | +------+ +------+ 128 | | i8 |----->| 1 B | 129 | +------+ +------+ 130 | | i16 |----->| 2 B | 131 | +------+ +------+ 132 | | i32 |----->| 4 B | 133 | +------+ +------+ 134 | | i64 |----->| 8 B | 135 | +------+ +------+ 136 | | i128 |----->| 16 B | 137 | +------+ +------+ 138 | | isize|----->| 4 B / 8 B | 139 | +------+ +----------+ 140 | ``` 141 | 142 | ### Conclusión 143 | 144 | Los tipos enteros con signo en Rust (`i8`, `i16`, `i32`, `i64`, `i128`, `isize`) son fundamentales para manejar números enteros en diversas aplicaciones. Comprender las diferencias en tamaño y rango, así como los métodos comunes para trabajar con ellos, permite a los desarrolladores escribir código eficiente y preciso. Estos tipos proporcionan la flexibilidad necesaria para adaptarse a diferentes necesidades de almacenamiento y procesamiento en Rust. 145 | -------------------------------------------------------------------------------- /content/2.basic/2.variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Variables y Declaraciones' 3 | description: 'Profundizando en las Variables en Rust: Funcionamiento, Almacenamiento y Gestión de Memoria' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 240 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-01-variables-and-mutability' 16 | - name: 'Variables y declaraciones en Rust' 17 | english: false 18 | link: 'https://blog.rustlang-es.org/articles/variables-y-declaraciones' 19 | --- 20 | ## Profundizando en las Variables en Rust: Funcionamiento, Almacenamiento y Gestión de Memoria 21 | 22 | En Rust, las variables juegan un papel crucial en la gestión de datos y la memoria. Este blog post explorará a fondo cómo funcionan las variables en Rust, cómo se almacenan y gestionan en la memoria, y los diferentes tipos de declaración disponibles. 23 | 24 | ### 1. ¿Qué es una Variable en Rust? 25 | 26 | En Rust, una variable es un contenedor que puede almacenar un valor de un tipo específico. Las variables permiten a los programas almacenar y manipular datos de manera eficiente. A diferencia de algunos lenguajes, las variables en Rust son **inmutables** por defecto, lo que significa que no pueden ser reasignadas después de su declaración a menos que se especifiquen como mutables. 27 | 28 | ### 2. Declaración e Inicialización de Variables 29 | 30 | La declaración de una variable en Rust se realiza utilizando la palabra clave `let`. Aquí hay un ejemplo básico: 31 | 32 | ```rust 33 | fn main() { 34 | let x = 5; 35 | println!("El valor de x es: {x}"); 36 | } 37 | ``` 38 | 39 | En este ejemplo: 40 | - `let x = 5;` declara una variable `x` y la inicializa con el valor `5`. 41 | - `println!("El valor de x es: {x}");` imprime el valor de `x` en la pantalla. 42 | 43 | ### 3. Mutabilidad 44 | 45 | En la programación un problema común es que los desarrolladores crean variables y suele re utilizarlas bastante sin saber su uso en otro momento. 46 | 47 | Por lo que inicialmente se espera que tenga un valor pero en entre un punto y otro se modifica ese valor, eso crea un error, se esperaba que ese valor permanezca con el estado inicial a lo largo de su ejecución. 48 | 49 | En Rust, para solucionar ese problema se tomo la medida de que toda variable sea inmutable por defecto. 50 | 51 | Es decir, a menos que no sea declarada para que sea modificada por futuros programadores esa variable no puede cambiar de valor. 52 | 53 | Para permitir que una variable sea reasignada, debes declararla como mutable usando la palabra clave `mut`: 54 | 55 | ```rust 56 | fn main() { 57 | let mut x = 5; 58 | println!("El valor de x es: {x}"); 59 | x = 6; 60 | println!("El valor de x ahora es: {x}"); 61 | } 62 | ``` 63 | 64 | En este ejemplo: 65 | - `let mut x = 5;` declara una variable mutable `x` y la inicializa con el valor `5`. 66 | - `x = 6;` reasigna `x` con el valor `6`. 67 | 68 | ### 4. Tipos de Datos y Inferencia de Tipos 69 | 70 | Rust es un lenguaje de programación fuertemente tipado, lo que significa que cada variable tiene un tipo específico. Los tipos básicos incluyen: 71 | 72 | - **Enteros** (`i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `u8`, `u16`, `u32`, `u64`, `u128`, `usize`) 73 | - **Flotantes** (`f32`, `f64`) 74 | - **Booleanos** (`bool`) 75 | - **Caracteres** (`char`) 76 | - **Cadenas** (`String`) 77 | 78 | > En otros topicos se detalla mejor cada tipo de dato 79 | 80 | Por lo general Rust puede inferir automáticamente el tipo de una variable basándose en el valor asignado, pero también puedes especificar explícitamente el tipo: 81 | 82 | ```rust 83 | fn main() { 84 | let x: i32 = 5; 85 | let y: f64 = 3.14; 86 | let z: bool = true; 87 | println!("x: {}, y: {}, z: {}", x, y, z); 88 | } 89 | ``` 90 | 91 | ### 5. Gestión de Memoria 92 | 93 | Rust utiliza un sistema de gestión de memoria basado en la propiedad y el préstamo. Cada variable en Rust tiene un propietario, y la memoria se libera automáticamente cuando el propietario sale del alcance. Esto elimina la necesidad de un recolector de basura (GC) y reduce la sobrecarga de memoria. 94 | 95 | #### Almacenamiento en Stack y Heap 96 | 97 | - **Stack:** Las variables de tipos primitivos (como enteros y booleanos) se almacenan en la pila (stack). El acceso a la memoria de la pila es rápido y eficiente. 98 | - **Heap:** Las estructuras de datos complejas (como `String` y `Vec`) se almacenan en el montón (heap). El acceso a la memoria del montón es más lento, pero permite una mayor flexibilidad en la gestión de la memoria. 99 | 100 | ```rust 101 | fn main() { 102 | let s1 = String::from("Hello"); 103 | let s2 = s1; // s1 se mueve a s2 104 | // println!("{}", s1); // Error: s1 ya no es válido 105 | println!("{}", s2); 106 | } 107 | ``` 108 | 109 | En este ejemplo, `s1` se mueve a `s2`, y `s1` ya no es válido. Rust previene errores comunes relacionados con la memoria mediante estas reglas estrictas de propiedad. 110 | 111 | #### Conclusión 112 | 113 | Las variables en Rust son fundamentales para la gestión de datos y la memoria. La combinación de mutabilidad controlada, tipos estrictos, y un sistema de propiedad robusto hace que Rust sea seguro y eficiente. Entender cómo funcionan las variables y cómo se gestionan en memoria es esencial para escribir programas efectivos en Rust. Al dominar estos conceptos, estarás bien encaminado para aprovechar al máximo este potente lenguaje. ¡Feliz codificación! 114 | -------------------------------------------------------------------------------- /content/2.basic/20.str.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'str' 3 | description: 'El Tipo de Dato `str` en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -50 10 | y: 400 11 | width: 280 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: '' 16 | - name: 'Ferrous System' 17 | english: true 18 | link: '' 19 | - name: 'Ferrocene Language Specification' 20 | english: true 21 | link: 'https://public-docs.ferrocene.dev/main/specification/types-and-traits.html#str-type' 22 | --- 23 | ## El Tipo de Dato `str` en Rust 24 | 25 | En Rust, el tipo de dato `str` es fundamental para trabajar con cadenas de caracteres. A diferencia de muchos otros lenguajes, Rust trata las cadenas de forma única, lo que puede parecer complicado al principio, pero proporciona una gran eficiencia y seguridad. Este artículo detalla las características del tipo `str`, sus usos, métodos comunes y cómo manejarlo en memoria. 26 | 27 | ### Características del Tipo `str` 28 | 29 | #### 1. Inmutabilidad 30 | - **Descripción:** En Rust, las cadenas de tipo `str` son inmutables. Esto significa que una vez creada, una cadena `str` no puede ser modificada. 31 | - **Ventaja:** La inmutabilidad garantiza la seguridad y coherencia de los datos a lo largo de la ejecución del programa. 32 | 33 | #### 2. Almacenamiento en Memoria 34 | - **Descripción:** El tipo `str` en Rust se almacena como una secuencia contigua de bytes en memoria. 35 | - **Codificación:** Las cadenas `str` están codificadas en UTF-8, lo que permite representar una amplia variedad de caracteres Unicode. 36 | - **Referencia:** En general, las cadenas `str` se manipulan mediante referencias (`&str`) para evitar copias innecesarias y mejorar el rendimiento. 37 | 38 | #### 3. Tamaño Dinámico 39 | - **Descripción:** El tamaño de un `str` está determinado en tiempo de ejecución, lo que lo convierte en un tipo de tamaño dinámico (DST, por sus siglas en inglés). 40 | - **Manipulación:** Para trabajar con `str`, generalmente utilizamos una referencia (`&str`) que incluye un puntero al inicio de la cadena y una longitud que indica su tamaño. 41 | 42 | ### Usos del Tipo `str` 43 | 44 | - **Texto Inmutable:** Se utiliza para representar texto que no necesita ser modificado, como mensajes de error, etiquetas y textos constantes. 45 | - **Comparaciones y Búsquedas:** Es útil para realizar comparaciones y búsquedas dentro de cadenas de texto, asegurando eficiencia y seguridad. 46 | - **Datos Multilingües:** Gracias a su codificación en UTF-8, `str` es ideal para manejar texto en múltiples idiomas, incluidos caracteres especiales y emojis. 47 | 48 | ### Métodos Más Comunes 49 | 50 | Aunque el tipo `str` no tiene métodos asociados directamente, Rust proporciona una serie de funciones y métodos a través del tipo de referencia `&str` para manipular y trabajar con cadenas de manera efectiva. Aquí algunos de los métodos más utilizados: 51 | 52 | #### 1. `len()` 53 | - **Descripción:** Devuelve la longitud de la cadena en bytes. 54 | - **Ejemplo:** 55 | 56 | ```rust 57 | let s = "Hola, mundo!"; 58 | println!("La longitud de s es: {}", s.len()); 59 | ``` 60 | 61 | #### 2. `is_empty()` 62 | - **Descripción:** Verifica si la cadena está vacía. 63 | - **Ejemplo:** 64 | 65 | ```rust 66 | let s = ""; 67 | println!("¿Está s vacía?: {}", s.is_empty()); 68 | ``` 69 | 70 | #### 3. `contains()` 71 | - **Descripción:** Comprueba si una subcadena está presente en la cadena. 72 | - **Ejemplo:** 73 | 74 | ```rust 75 | let s = "Hola, mundo!"; 76 | println!("¿Contiene 'mundo'?: {}", s.contains("mundo")); 77 | ``` 78 | 79 | #### 4. `split()` 80 | - **Descripción:** Divide la cadena en subcadenas basadas en un delimitador. 81 | - **Ejemplo:** 82 | 83 | ```rust 84 | let s = "Hola, mundo!"; 85 | for part in s.split(", ") { 86 | println!("{}", part); 87 | } 88 | ``` 89 | 90 | #### 5. `to_uppercase()` 91 | - **Descripción:** Convierte la cadena a mayúsculas. 92 | - **Ejemplo:** 93 | 94 | ```rust 95 | let s = "Hola, mundo!"; 96 | println!("En mayúsculas: {}", s.to_uppercase()); 97 | ``` 98 | 99 | ### Ejemplo de Uso en Rust 100 | 101 | ```rust 102 | fn main() { 103 | let saludo: &str = "Hola, mundo!"; 104 | 105 | // Métodos comunes 106 | println!("Longitud: {}", saludo.len()); 107 | println!("¿Está vacío?: {}", saludo.is_empty()); 108 | println!("¿Contiene 'mundo'?: {}", saludo.contains("mundo")); 109 | 110 | // División de la cadena 111 | for parte in saludo.split(", ") { 112 | println!("Parte: {}", parte); 113 | } 114 | 115 | // Conversión a mayúsculas 116 | println!("En mayúsculas: {}", saludo.to_uppercase()); 117 | } 118 | ``` 119 | 120 | ### Espacio en Memoria 121 | 122 | En Rust, el tipo `str` es almacenado en memoria de manera contigua y codificado en UTF-8, permitiendo una representación eficiente y compacta de texto Unicode. A continuación, se ilustra cómo se gestiona en memoria: 123 | 124 | **Gráfico: Almacenamiento de una Cadena `str` en Memoria** 125 | 126 | ```plaintext 127 | +---+---+---+---+---+---+---+---+---+---+---+---+ 128 | | H | o | l | a | , | | m | u | n | d | o | ! | 129 | +---+---+---+---+---+---+---+---+---+---+---+---+ 130 | 0 1 2 3 4 5 6 7 8 9 10 11 131 | 132 | Dirección de memoria contigua: 133 | Puntero al inicio -> 0 134 | Longitud en bytes -> 12 135 | ``` 136 | 137 | ### Conclusión 138 | 139 | El tipo `str` en Rust es una poderosa herramienta para trabajar con cadenas de texto de manera segura y eficiente. Su inmutabilidad, codificación en UTF-8 y manejo dinámico de tamaños lo hacen ideal para aplicaciones que requieren un manejo robusto de texto. Comprender cómo utilizar `str` y sus métodos asociados permite a los desarrolladores escribir código más seguro y eficiente en Rust. 140 | -------------------------------------------------------------------------------- /content/2.basic/21.complex-types.yml: -------------------------------------------------------------------------------- 1 | title: 'Tipos de Datos Complejos' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: -50 8 | y: 480 9 | width: 320 10 | align: 'left' 11 | sourcePosition: 12 | none: 'top' 13 | targetPosition: 14 | basic: 'left' 15 | -------------------------------------------------------------------------------- /content/2.basic/22.tuples.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'tupla' 3 | description: 'Las Tuplas en Rust: Una Introducción' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -50 10 | y: 520 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types#el-tipo-tupla' 16 | - name: 'Libro de Referencia Rust' 17 | english: true 18 | link: 'https://doc.rust-lang.org/reference/types/tuple.html#tuple-types' 19 | --- 20 | ## Las Tuplas en Rust: Una Introducción 21 | 22 | En Rust, las tuplas son un tipo de dato versátil y poderoso que permite agrupar múltiples valores de diferentes tipos en una única entidad. Esta funcionalidad es especialmente útil para retornar múltiples valores de una función o para agrupar datos relacionados de manera estructurada. En este blog post, exploraremos en detalle las características, usos y métodos comunes de las tuplas en Rust. 23 | 24 | ### Características de las Tuplas 25 | 26 | #### 1. Heterogeneidad 27 | - **Descripción:** Las tuplas pueden contener valores de diferentes tipos. Esto las diferencia de las arrays y vectors, que solo pueden contener valores del mismo tipo. 28 | - **Ejemplo:** 29 | 30 | ```rust 31 | let tupla: (i32, f64, char) = (42, 3.14, 'a'); 32 | ``` 33 | 34 | #### 2. Tamaño Fijo 35 | - **Descripción:** El tamaño de una tupla se define en el momento de su creación y no puede cambiar. Cada tupla tiene un número fijo de elementos, y este número se debe conocer en tiempo de compilación. 36 | - **Ejemplo:** 37 | 38 | ```rust 39 | let tupla: (i32, i32) = (1, 2); // Tamaño fijo de 2 elementos 40 | ``` 41 | 42 | #### 3. Acceso por Índice 43 | - **Descripción:** Los elementos de una tupla se pueden acceder por su índice, comenzando desde cero. 44 | - **Ejemplo:** 45 | 46 | ```rust 47 | let tupla: (i32, f64, char) = (42, 3.14, 'a'); 48 | println!("El primer elemento es: {}", tupla.0); 49 | println!("El segundo elemento es: {}", tupla.1); 50 | println!("El tercer elemento es: {}", tupla.2); 51 | ``` 52 | 53 | ### Usos de las Tuplas 54 | 55 | - **Retorno de Múltiples Valores:** Las tuplas son ideales para funciones que necesitan retornar múltiples valores. 56 | - **Agrupación de Datos Relacionados:** Permiten agrupar datos relacionados de diferentes tipos en una sola estructura. 57 | - **Desestructuración:** Facilita la extracción de valores individuales de una tupla. 58 | 59 | ### Ejemplo de Uso en Rust 60 | 61 | ```rust 62 | fn main() { 63 | let coordenadas: (f64, f64) = (6.0, 8.0); 64 | 65 | // Desestructuración de la tupla 66 | let (x, y) = coordenadas; 67 | println!("Coordenadas: x = {}, y = {}", x, y); 68 | 69 | // Acceso por índice 70 | println!("El primer elemento es: {}", coordenadas.0); 71 | println!("El segundo elemento es: {}", coordenadas.1); 72 | 73 | // Función que retorna una tupla 74 | let resultado = sumar_y_multiplicar(3, 4); 75 | println!("Suma: {}, Multiplicación: {}", resultado.0, resultado.1); 76 | } 77 | 78 | fn sumar_y_multiplicar(a: i32, b: i32) -> (i32, i32) { 79 | (a + b, a * b) 80 | } 81 | ``` 82 | 83 | ### Métodos Más Comunes 84 | 85 | Aunque las tuplas no tienen métodos específicos asociados como otros tipos en Rust, se pueden manipular mediante desestructuración y acceso por índice. Sin embargo, algunas operaciones comunes incluyen: 86 | 87 | - **Desestructuración:** Permite asignar los valores de una tupla a variables individuales. 88 | - **Acceso por Índice:** Acceso directo a los elementos individuales de una tupla usando su índice. 89 | 90 | ### Desestructuración de Tuplas 91 | 92 | La desestructuración permite desempaquetar una tupla en sus componentes individuales. Esto es útil cuando se necesitan trabajar con los valores por separado. 93 | 94 | ```rust 95 | fn main() { 96 | let persona: (&str, i32) = ("Alice", 30); 97 | 98 | // Desestructuración 99 | let (nombre, edad) = persona; 100 | println!("Nombre: {}, Edad: {}", nombre, edad); 101 | } 102 | ``` 103 | 104 | ### Acceso por Índice 105 | 106 | Cada elemento de una tupla se puede acceder utilizando el índice correspondiente, que empieza desde cero. 107 | 108 | ```rust 109 | fn main() { 110 | let colores: (&str, &str, &str) = ("rojo", "verde", "azul"); 111 | 112 | println!("Primer color: {}", colores.0); 113 | println!("Segundo color: {}", colores.1); 114 | println!("Tercer color: {}", colores.2); 115 | } 116 | ``` 117 | 118 | ### Espacio en Memoria 119 | 120 | Las tuplas ocupan un tamaño en memoria que es la suma del tamaño de cada uno de sus elementos. Esto garantiza que no haya desperdicio de memoria y que las operaciones con tuplas sean eficientes. 121 | 122 | **Gráfico: Representación de una Tupla en Memoria** 123 | 124 | ```plaintext 125 | +-----------+-----------+-----------+ 126 | | i32 | f64 | char | 127 | +-----------+-----------+-----------+ 128 | | 4 bytes | 8 bytes | 4 bytes | 129 | +-----------+-----------+-----------+ 130 | ``` 131 | 132 | ### Conclusión 133 | 134 | Las tuplas en Rust son una herramienta poderosa para agrupar múltiples valores de diferentes tipos en una única entidad. Su capacidad para ser desestructuradas y acceder a sus elementos por índice las hace extremadamente útiles para una variedad de aplicaciones, desde retornar múltiples valores de funciones hasta agrupar datos relacionados. Al entender cómo funcionan las tuplas y cómo utilizarlas de manera efectiva, los desarrolladores pueden escribir código más limpio y eficiente en Rust. 135 | -------------------------------------------------------------------------------- /content/2.basic/23.array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Arreglos' 3 | description: 'Los Arreglos en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 32 10 | y: 520 11 | width: 118 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-02-data-types#el-tipo-arreglo' 16 | - name: 'Libro de Referencia Rust' 17 | english: true 18 | link: 'https://doc.rust-lang.org/reference/types/array.html' 19 | --- 20 | ## Los Arreglos en Rust 21 | 22 | En Rust, los arreglos (arrays) son una de las estructuras de datos más básicas y esenciales. Los arreglos permiten almacenar múltiples valores del mismo tipo en una secuencia contigua de elementos. Este blog post explora en detalle las características, usos, métodos comunes y manejo en memoria de los arreglos en Rust. 23 | 24 | ### Características de los Arreglos en Rust 25 | 26 | #### 1. Homogeneidad 27 | - **Descripción:** Todos los elementos de un arreglo deben ser del mismo tipo. 28 | - **Ejemplo:** 29 | 30 | ```rust 31 | let numeros: [i32; 5] = [1, 2, 3, 4, 5]; 32 | ``` 33 | 34 | #### 2. Tamaño Fijo 35 | - **Descripción:** El tamaño de un arreglo en Rust se debe conocer en tiempo de compilación y no puede cambiar. 36 | - **Ejemplo:** 37 | 38 | ```rust 39 | let letras: [char; 3] = ['a', 'b', 'c']; 40 | ``` 41 | 42 | #### 3. Acceso por Índice 43 | - **Descripción:** Los elementos de un arreglo se pueden acceder mediante índices, comenzando desde cero. 44 | - **Ejemplo:** 45 | 46 | ```rust 47 | let dias: [&str; 7] = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"]; 48 | println!("El primer día es: {}", dias[0]); 49 | ``` 50 | 51 | ### Usos de los Arreglos 52 | 53 | - **Almacenamiento de Datos:** Los arreglos son útiles para almacenar colecciones de datos del mismo tipo, como números, caracteres o strings. 54 | - **Iteraciones y Operaciones:** Facilitan la realización de operaciones repetitivas sobre una colección de elementos. 55 | - **Acceso Rápido:** Proporcionan acceso rápido a los elementos a través de índices. 56 | 57 | ### Ejemplo de Uso en Rust 58 | 59 | ```rust 60 | fn main() { 61 | let numeros: [i32; 5] = [1, 2, 3, 4, 5]; 62 | 63 | // Acceso por índice 64 | println!("El primer número es: {}", numeros[0]); 65 | 66 | // Iteración sobre el arreglo 67 | for num in numeros.iter() { 68 | println!("Número: {}", num); 69 | } 70 | 71 | // Modificación de un elemento 72 | let mut mutable_numeros = [1, 2, 3, 4, 5]; 73 | mutable_numeros[0] = 10; 74 | println!("El primer número modificado es: {}", mutable_numeros[0]); 75 | } 76 | ``` 77 | 78 | ### Métodos Comunes 79 | 80 | Aunque los arreglos en Rust no tienen métodos asociados como las colecciones más complejas, se pueden utilizar en combinación con slices y otros tipos para realizar diversas operaciones. Aquí algunos de los métodos y usos más comunes: 81 | 82 | #### 1. `len()` 83 | - **Descripción:** Devuelve la longitud del arreglo. 84 | - **Ejemplo:** 85 | 86 | ```rust 87 | let numeros: [i32; 5] = [1, 2, 3, 4, 5]; 88 | println!("La longitud del arreglo es: {}", numeros.len()); 89 | ``` 90 | 91 | #### 2. Iteración con `iter()` 92 | - **Descripción:** Devuelve un iterador sobre el arreglo. 93 | - **Ejemplo:** 94 | 95 | ```rust 96 | let frutas: [&str; 3] = ["Manzana", "Banana", "Cereza"]; 97 | for fruta in frutas.iter() { 98 | println!("Fruta: {}", fruta); 99 | } 100 | ``` 101 | 102 | #### 3. Acceso Mutable 103 | - **Descripción:** Permite modificar los elementos del arreglo. 104 | - **Ejemplo:** 105 | 106 | ```rust 107 | let mut letras: [char; 3] = ['a', 'b', 'c']; 108 | letras[0] = 'z'; 109 | println!("La primera letra modificada es: {}", letras[0]); 110 | ``` 111 | 112 | ### Espacio en Memoria 113 | 114 | El espacio en memoria ocupado por un arreglo es contiguo y depende del tipo y la cantidad de elementos que contiene. A continuación, se ilustra cómo se gestiona en memoria un arreglo: 115 | 116 | **Gráfico: Representación de un Arreglo en Memoria** 117 | 118 | ```plaintext 119 | +-----------+-----------+-----------+-----------+-----------+ 120 | | Elemento1 | Elemento2 | Elemento3 | Elemento4 | Elemento5 | 121 | +-----------+-----------+-----------+-----------+-----------+ 122 | | i32 | i32 | i32 | i32 | i32 | 123 | +-----------+-----------+-----------+-----------+-----------+ 124 | ``` 125 | 126 | ### Ventajas y Desventajas de los Arreglos 127 | 128 | #### Ventajas 129 | - **Acceso Rápido:** Proporcionan acceso constante a los elementos mediante índices. 130 | - **Eficiencia de Memoria:** Ocupan un bloque contiguo de memoria, lo que mejora la eficiencia de acceso y manipulación. 131 | 132 | #### Desventajas 133 | - **Tamaño Fijo:** No se pueden redimensionar una vez creados, lo que puede ser limitante en algunos casos. 134 | - **Homogeneidad:** Solo pueden almacenar elementos del mismo tipo. 135 | 136 | ### Conclusión 137 | 138 | Los arreglos en Rust son una herramienta fundamental para almacenar y manipular colecciones de datos del mismo tipo de manera eficiente y segura. Aunque tienen un tamaño fijo y solo pueden contener elementos del mismo tipo, su simplicidad y rapidez de acceso los hacen ideales para muchas aplicaciones comunes. Al comprender cómo utilizar arreglos y sus métodos asociados, los desarrolladores pueden escribir código más eficiente y organizado en Rust. 139 | -------------------------------------------------------------------------------- /content/2.basic/24.slices.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Slice' 3 | description: 'Comprendiendo los Slices en Rust: Rendimiento, Uso y Comparación con Arreglos' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 155 10 | y: 520 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch04-03-slices#string-slices' 16 | - name: 'Libro de Referencia Rust' 17 | english: true 18 | link: '' 19 | --- 20 | ## Comprendiendo los Slices en Rust: Rendimiento, Uso y Comparación con Arreglos 21 | 22 | Los slices en Rust son una de las características más poderosas y flexibles del lenguaje. A diferencia de los arreglos, los slices permiten trabajar con subsecciones de datos sin necesidad de copiar o duplicar los datos originales. En este blog post, exploraremos en detalle las características, el rendimiento, la representación en memoria y las diferencias entre los slices y los arreglos. 23 | 24 | ### ¿Qué son los Slices? 25 | 26 | Los slices son vistas de datos que permiten acceder a una porción de una colección, como un arreglo o una cadena (`str`). Son especialmente útiles cuando se necesita trabajar con subsecciones de datos sin crear copias adicionales. Los slices se representan mediante referencias y tienen un tamaño dinámico determinado en tiempo de ejecución. 27 | 28 | ### Características de los Slices 29 | 30 | #### 1. Tamaño Dinámico 31 | - **Descripción:** A diferencia de los arreglos, el tamaño de un slice no se conoce en tiempo de compilación y puede cambiar. 32 | - **Ejemplo:** 33 | 34 | ```rust 35 | let arreglo = [1, 2, 3, 4, 5]; 36 | let slice = &arreglo[1..4]; // Slice que incluye los elementos de índice 1 a 3 37 | ``` 38 | 39 | #### 2. Inmutabilidad por Defecto 40 | - **Descripción:** Los slices son inmutables por defecto, pero se pueden crear slices mutables. 41 | - **Ejemplo:** 42 | 43 | ```rust 44 | let mut arreglo = [1, 2, 3, 4, 5]; 45 | let slice_mut = &mut arreglo[1..4]; // Slice mutable 46 | ``` 47 | 48 | #### 3. Representación en Memoria 49 | - **Descripción:** Los slices almacenan una referencia al primer elemento y la longitud del slice. Esta estructura les permite ser eficientes en términos de memoria y rendimiento. 50 | - **Ejemplo:** 51 | 52 | ```plaintext 53 | Slice: &arreglo[1..3] 54 | Memoria: 55 | +-----------+-----------+-----------+-----------+-----------+ 56 | | Elemento0 | Elemento1 | Elemento2 | Elemento3 | Elemento4 | 57 | +-----------+-----------+-----------+-----------+-----------+ 58 | | 1 | 2 | 3 | 4 | 5 | 59 | +-----------+-----------+-----------+-----------+-----------+ 60 | ^ ^ 61 | | | 62 | Referencia Longitud 63 | 1 ... 3 64 | ``` 65 | 66 | ### Diferencias entre Slices y Arreglos 67 | 68 | | Característica | Arreglo | Slice | 69 | |----------------|---------|-------| 70 | | Tamaño | Fijo | Dinámico | 71 | | Memoria | Contigua y estática | Referencia a un segmento de datos | 72 | | Flexibilidad | Menor | Mayor (permite trabajar con subsecciones) | 73 | | Mutabilidad | Puede ser mutable o inmutable | Inmutable por defecto, puede ser mutable | 74 | | Coste de Copia | Copia completa | No requiere copia, trabaja con referencias | 75 | 76 | ### Ventajas de los Slices 77 | 78 | - **Eficiencia de Memoria:** No requieren copiar datos, lo que los hace eficientes en términos de uso de memoria. 79 | - **Flexibilidad:** Permiten trabajar con partes de colecciones sin la necesidad de manipular la colección completa. 80 | - **Seguridad:** Ofrecen seguridad en tiempo de compilación, garantizando que no se acceda fuera de los límites del slice. 81 | 82 | ### Usos Comunes de los Slices 83 | 84 | - **Subsecciones de Arreglos:** Extraer y manipular partes específicas de un arreglo. 85 | - **Procesamiento de Datos:** Pasar partes de colecciones a funciones para su procesamiento. 86 | - **Manejo de Cadenas:** Trabajar con partes de cadenas sin duplicar los datos. 87 | 88 | ### Ejemplo de Uso en Rust 89 | 90 | ```rust 91 | fn main() { 92 | let arreglo = [10, 20, 30, 40, 50]; 93 | 94 | // Crear un slice inmutable 95 | let slice = &arreglo[1..4]; 96 | println!("Slice: {:?}", slice); 97 | 98 | // Crear un slice mutable 99 | let mut arreglo_mut = [1, 2, 3, 4, 5]; 100 | let slice_mut = &mut arreglo_mut[2..4]; 101 | slice_mut[0] = 10; // Modifica el elemento en el slice 102 | println!("Arreglo modificado: {:?}", arreglo_mut); 103 | } 104 | 105 | ``` 106 | 107 | ### Representación en Memoria de los Slices 108 | 109 | Los slices se representan en memoria como una referencia al primer elemento del slice y la longitud del slice. Esta representación permite un acceso eficiente y seguro a los datos subyacentes. 110 | 111 | **Gráfico: Representación de un Slice en Memoria** 112 | 113 | ```plaintext 114 | Slice: &arreglo[1..3] 115 | Memoria: 116 | +-----------+-----------+-----------+-----------+-----------+ 117 | | Elemento0 | Elemento1 | Elemento2 | Elemento3 | Elemento4 | 118 | +-----------+-----------+-----------+-----------+-----------+ 119 | | 10 | 20 | 30 | 40 | 50 | 120 | +-----------+-----------+-----------+-----------+-----------+ 121 | ^ ^ 122 | | | 123 | Referencia Longitud 124 | 1 ... 3 125 | ``` 126 | 127 | ### Rendimiento de los Slices 128 | 129 | El uso de slices es altamente eficiente porque evita la necesidad de copiar datos. Los slices simplemente referencian una porción de una colección existente, lo que reduce el coste de operaciones de memoria y mejora el rendimiento en operaciones de acceso y manipulación de datos. 130 | 131 | ### Conclusión 132 | 133 | Los slices en Rust son una herramienta poderosa para trabajar con subsecciones de datos de manera eficiente y segura. Al entender cómo funcionan los slices, cómo se representan en memoria y cómo se diferencian de los arreglos, los desarrolladores pueden aprovechar mejor las capacidades de Rust para escribir código más limpio, eficiente y seguro. Los slices no solo mejoran el rendimiento de las operaciones de manipulación de datos, sino que también proporcionan una mayor flexibilidad en el diseño de programas. 134 | -------------------------------------------------------------------------------- /content/2.basic/27.string.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'String' 3 | description: 'El Tipo de Dato `String` en Rust: Un Análisis Completo' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 145 10 | y: 560 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch08-02-strings' 16 | - name: 'Post acerca del manejo correcto de Strings en Rust' 17 | english: false 18 | link: 'https://blog.rustlang-es.org/articles/strings' 19 | - name: 'Comprehensive Rust' 20 | english: false 21 | link: 'https://google.github.io/comprehensive-rust/es/std-types/string.html' 22 | - name: 'Documentacion Oficial sobre el Formateo de texto' 23 | english: true 24 | link: 'https://doc.rust-lang.org/std/fmt' 25 | --- 26 | ## El Tipo de Dato `String` en Rust 27 | 28 | El tipo de dato `String` en Rust es una representación dinámica de una cadena de texto, gestionada en heap, lo que le permite crecer y reducirse en tamaño en tiempo de ejecución. En este post, exploraremos cómo funciona `String` en memoria, cuándo es recomendable usarlo, por qué no tiene la trait `Copy` implementada, el concepto de `Cow`, el uso del macro `format!`, y el coste computacional de su uso, destacando la eficiencia de Rust. 29 | 30 | ### ¿Qué es `String` en Rust? 31 | 32 | En Rust, `String` es un tipo de dato dinámico que permite almacenar y manipular cadenas de texto. A diferencia del tipo `&str`, que es una referencia a una cadena de texto inmutable y con una longitud fija, `String` es mutable y puede crecer o reducirse en tamaño. 33 | 34 | ### Funcionamiento en Memoria 35 | 36 | Una instancia de `String` en Rust se compone de tres partes principales: 37 | 38 | 1. **Puntero a los datos:** Apunta al comienzo del bloque de memoria donde se almacenan los datos de la cadena en el heap. 39 | 2. **Capacidad:** Indica cuánta memoria ha sido reservada para la cadena, lo que puede ser más que la longitud actual de la cadena. 40 | 3. **Longitud:** Representa el número de bytes utilizados actualmente en el bloque de memoria. 41 | 42 | #### Gráfico: Representación en Memoria de un `String` 43 | 44 | ```plaintext 45 | +-----------------+ 46 | | Puntero | --> [ H e l l o ] 47 | +-----------------+ 48 | | Capacidad: 10 | 49 | +-----------------+ 50 | | Longitud: 5 | 51 | +-----------------+ 52 | ``` 53 | 54 | ### ¿Cuándo Usar `String`? 55 | 56 | Es recomendable usar `String` cuando: 57 | 58 | - Necesitas una cadena de texto mutable. 59 | - La longitud de la cadena no es conocida en tiempo de compilación. 60 | - La cadena de texto necesita ser modificada, concatenada o manipulada dinámicamente. 61 | 62 | Para cadenas de texto estáticas y de longitud conocida, es preferible usar `&str`, ya que es más eficiente en términos de memoria y rendimiento. 63 | 64 | ### Por Qué `String` No Implementa `Copy` 65 | 66 | La trait `Copy` en Rust indica que una variable puede ser copiada simplemente haciendo una copia bit a bit de su valor. Sin embargo, `String` no implementa `Copy` debido a que copiar un `String` implicaría duplicar el bloque de memoria en el heap al que apunta. Esto sería costoso en términos de rendimiento y podría causar problemas de administración de memoria, como fugas de memoria si no se maneja correctamente. 67 | 68 | ### El Concepto de `Cow` 69 | 70 | `Cow` (Clone on Write) es un tipo en Rust que permite optimizar las operaciones que pueden requerir clonación de datos. `Cow` puede ser una referencia inmutable a los datos o una copia de los datos si se necesita una versión mutable. 71 | 72 | #### Ejemplo de Uso de `Cow` 73 | 74 | ```rust 75 | use std::borrow::Cow; 76 | 77 | fn procesar_texto(texto: &str) -> Cow { 78 | if texto.contains("rust") { 79 | let mut owned = texto.to_owned(); 80 | owned.push_str(" is awesome!"); 81 | Cow::Owned(owned) 82 | } else { 83 | Cow::Borrowed(texto) 84 | } 85 | } 86 | 87 | fn main() { 88 | let texto = "I love rust"; 89 | let resultado = procesar_texto(texto); 90 | println!("{}", resultado); 91 | } 92 | ``` 93 | 94 | ### El Macro `format!` 95 | 96 | El macro `format!` en Rust es similar a `printf` en C y otros lenguajes. Permite construir cadenas de texto a partir de variables y literales. 97 | 98 | #### Ejemplo de Uso de `format!` 99 | 100 | ```rust 101 | fn main() { 102 | let nombre = "Alice"; 103 | let edad = 30; 104 | let mensaje = format!("Hola, {nombre}. Tienes {edad} años."); 105 | println!("{mensaje}"); 106 | } 107 | ``` 108 | 109 | ### Coste Computacional de Usar `String` 110 | 111 | Manipular cadenas de texto dinámicas con `String` implica ciertas operaciones de gestión de memoria que pueden ser costosas: 112 | 113 | - **Asignación en el Heap:** Crear y expandir una `String` implica asignar y posiblemente realocar memoria en el heap. 114 | - **Copia de Datos:** Operaciones que duplican o concatenan `String`s pueden ser costosas si se requiere copiar grandes cantidades de datos. 115 | 116 | Sin embargo, Rust es extremadamente eficiente en la gestión de memoria y rendimiento gracias a su sistema de préstamos y propiedades de tiempo de vida, que minimizan las asignaciones y copias innecesarias. 117 | 118 | ### Optimización y Eficiencia en Rust 119 | 120 | A pesar de los posibles costes computacionales, Rust proporciona varias características que optimizan el uso de `String`: 121 | 122 | - **Reserva Anticipada:** Usar `String::with_capacity` permite reservar memoria anticipadamente, reduciendo la necesidad de realocaciones. 123 | 124 | ```rust 125 | fn main() { 126 | let mut s = String::with_capacity(10); 127 | s.push_str("Hola"); 128 | println!("{}", s); 129 | } 130 | ``` 131 | 132 | - **Métodos Eficientes:** Los métodos de `String` están optimizados para operaciones comunes, como concatenación y búsqueda, aprovechando las características de bajo nivel de Rust. 133 | 134 | ### Conclusión 135 | 136 | El tipo de dato `String` en Rust es una herramienta poderosa para trabajar con cadenas de texto dinámicas. Aunque puede implicar costes computacionales debido a la gestión de memoria, Rust optimiza estas operaciones para asegurar eficiencia. Al entender cómo funciona `String` en memoria, cuándo usarlo y cómo optimizar su uso, los desarrolladores pueden aprovechar al máximo las capacidades de Rust para manejar cadenas de texto de manera efectiva y segura. 137 | -------------------------------------------------------------------------------- /content/2.basic/28.range.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Rangos' 3 | description: 'Explorando los Rangos en Rust: Uso en Slices, Vectores, Iteraciones y Más' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -50 10 | y: 600 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial - Match Binding' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch18-03-pattern-syntax#-bindings' 16 | - name: 'Libro de Referencia Rust' 17 | english: true 18 | link: 'https://doc.rust-lang.org/reference/expressions/range-expr.html' 19 | - name: 'Documentacion Oficial sobre los Rangos' 20 | english: true 21 | link: 'https://doc.rust-lang.org/std/ops/struct.Range.html' 22 | --- 23 | ## Rangos en Rust 24 | 25 | En Rust, los rangos son una característica poderosa y versátil que facilita la manipulación de secuencias y colecciones de datos. Los rangos pueden ser utilizados en diversas situaciones, incluyendo slices, vectores, iteraciones, validaciones, y más. Este blog post ofrece una exploración detallada de los rangos en Rust, mostrando ejemplos prácticos y destacando su utilidad en diferentes contextos. 26 | 27 | > [!IMPORTANT] 28 | > Los rangos son una característica mas que un Tipo. 29 | 30 | ### Concepto Básico de Rangos en Rust 31 | 32 | Un rango en Rust se define utilizando la sintaxis `start..end` o `start..=end`, donde `start` es el valor inicial del rango y `end` es el valor final. La diferencia clave entre estas dos sintaxis es que `..` excluye el valor final, mientras que `..=` lo incluye. 33 | 34 | #### Ejemplo: 35 | 36 | ```rust 37 | fn main() { 38 | let rango_exclusivo = 0..5; // 0, 1, 2, 3, 4 39 | let rango_inclusivo = 0..=5; // 0, 1, 2, 3, 4, 5 40 | 41 | println!("Rango exclusivo: {:?}", rango_exclusivo); 42 | println!("Rango inclusivo: {:?}", rango_inclusivo); 43 | } 44 | ``` 45 | 46 | ### Uso de Rangos en Slices 47 | 48 | Los rangos son particularmente útiles cuando se trabaja con slices de arreglos. Permiten seleccionar una subsección de un arreglo de manera simple y eficiente. 49 | 50 | #### Ejemplo: 51 | 52 | ```rust 53 | fn main() { 54 | let arreglo = [1, 2, 3, 4, 5]; 55 | let slice = &arreglo[1..4]; // Selecciona los elementos en las posiciones 1, 2 y 3 56 | 57 | println!("Slice: {:?}", slice); // Output: [2, 3, 4] 58 | } 59 | ``` 60 | 61 | ### Rangos en Vectores 62 | 63 | De manera similar a los slices, los rangos también pueden ser utilizados para obtener subvecotres de un vector. Esto es útil cuando se necesita manipular o acceder a una parte específica del vector. 64 | 65 | #### Ejemplo: 66 | 67 | ```rust 68 | fn main() { 69 | let vector = vec![10, 20, 30, 40, 50]; 70 | let subvector = &vector[2..]; // Selecciona los elementos desde la posición 2 hasta el final 71 | 72 | println!("Subvector: {:?}", subvector); // Output: [30, 40, 50] 73 | } 74 | ``` 75 | 76 | ### Iteraciones con Rangos 77 | 78 | Los rangos son frecuentemente utilizados para iterar sobre secuencias de números. Esto es muy útil en bucles `for`, donde se necesita ejecutar un bloque de código un número específico de veces. 79 | 80 | #### Ejemplo: 81 | 82 | ```rust 83 | fn main() { 84 | for i in 0..5 { 85 | println!("Número: {}", i); // Output: 0, 1, 2, 3, 4 86 | } 87 | 88 | for j in 0..=5 { 89 | println!("Número: {}", j); // Output: 0, 1, 2, 3, 4, 5 90 | } 91 | } 92 | ``` 93 | 94 | ### Validaciones con Rangos 95 | 96 | Los rangos también se pueden utilizar para realizar validaciones, como verificar si un valor está dentro de un rango específico. 97 | 98 | #### Ejemplo: 99 | 100 | ```rust 101 | fn main() { 102 | let edad = 25; 103 | if (18..=30).contains(&edad) { 104 | println!("La edad está dentro del rango permitido."); 105 | } else { 106 | println!("La edad está fuera del rango permitido."); 107 | } 108 | } 109 | ``` 110 | 111 | ### Otras Situaciones Donde los Rangos Pueden Destacar 112 | 113 | 1. **Generación de Números:** Los rangos pueden ser utilizados para generar secuencias de números fácilmente. 114 | 2. **Operaciones en Colecciones:** Facilitan la selección y manipulación de subconjuntos de datos en colecciones. 115 | 3. **Particionamiento de Datos:** Permiten dividir datos en partes más pequeñas de manera eficiente. 116 | 117 | ### Gráficos: Visualizando Rangos 118 | 119 | #### Representación de Rangos en Slices 120 | 121 | ```plaintext 122 | Arreglo: [1, 2, 3, 4, 5] 123 | Slice (1..4): [2, 3, 4] 124 | 125 | +---+---+---+---+---+ 126 | | 1 | 2 | 3 | 4 | 5 | 127 | +---+---+---+---+---+ 128 | ^ ^ ^ ^ 129 | | | | | 130 | |---|---|---| 131 | ``` 132 | 133 | ### Conclusión 134 | 135 | Los rangos en Rust son una herramienta versátil que facilita la manipulación y acceso a secuencias de datos. Desde slices y vectores hasta iteraciones y validaciones, los rangos ofrecen una manera simple y eficiente de trabajar con subconjuntos de datos. Al comprender y aprovechar las capacidades de los rangos, los desarrolladores pueden escribir código más limpio, eficiente y expresivo en Rust. 136 | -------------------------------------------------------------------------------- /content/2.basic/3.const-and-statics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Constantes y Variables Estáticas' 3 | description: 'Constantes y variables Estáticas en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 280 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-01-variables-and-mutability#constantes' 16 | - name: 'Variables y declaraciones en Rust' 17 | english: false 18 | link: 'https://blog.rustlang-es.org/articles/variables-y-declaraciones' 19 | - name: 'Libro de Referencia - Constants' 20 | english: true 21 | link: 'https://doc.rust-lang.org/reference/items/constant-items.html' 22 | - name: 'Libro de Referencia - Statics' 23 | english: true 24 | link: 'https://doc.rust-lang.org/reference/items/static-items.html' 25 | --- 26 | # Constantes y Variables Estáticas en Rust 27 | 28 | Rust es un lenguaje de programación de sistemas conocido por su seguridad y rendimiento. Una de las características importantes que Rust ofrece para manejar valores que no cambian son las **constantes** y las **variables estáticas**. En este post, exploraremos qué son, cómo se declaran, cómo se almacenan en memoria y qué implicancias tienen, especialmente las constantes evaluadas en tiempo de compilación. 29 | 30 | ## Constantes en Rust 31 | 32 | ### Declaración y Uso 33 | 34 | Las constantes en Rust se declaran usando la palabra clave `const`. A diferencia de las variables normales, las constantes deben ser siempre inmutables y su tipo debe ser anotado explícitamente. Se pueden declarar en cualquier ámbito, incluyendo dentro de funciones. 35 | 36 | ```rust 37 | const MAX_POINTS: u32 = 100_000; 38 | ``` 39 | 40 | En este ejemplo, `MAX_POINTS` es una constante de tipo `u32` con un valor de `100,000`. Las constantes pueden ser de cualquier tipo primitivo o compuesto (como arreglos y tuplas), siempre y cuando su valor pueda ser evaluado en tiempo de compilación. 41 | 42 | ### Evaluación en Tiempo de Compilación 43 | 44 | Una de las grandes ventajas de las constantes en Rust es que son evaluadas en tiempo de compilación. Esto significa que el valor de la constante se calcula y se inserta directamente en el binario generado, eliminando la necesidad de calcular el valor en tiempo de ejecución, lo cual puede mejorar el rendimiento. 45 | 46 | ```rust 47 | const SECONDS_IN_A_DAY: u32 = 24 * 60 * 60; 48 | ``` 49 | 50 | Aquí, `SECONDS_IN_A_DAY` se calcula durante la compilación, asegurando que el cálculo no tenga que realizarse repetidamente en tiempo de ejecución. 51 | 52 | ## Variables Estáticas en Rust 53 | 54 | ### Declaración y Uso 55 | 56 | Las variables estáticas se declaran con la palabra clave `static`. A diferencia de las constantes, las variables estáticas pueden ser mutables (aunque esto es raramente recomendado debido a cuestiones de seguridad y concurrencia). 57 | 58 | ```rust 59 | static HELLO_WORLD: &str = "Hello, world!"; 60 | ``` 61 | 62 | En este ejemplo, `HELLO_WORLD` es una variable estática de tipo `&str`. 63 | 64 | ### Variables Estáticas Mutables 65 | 66 | Para declarar una variable estática mutable, se usa la palabra clave `mut` después de `static`. Es importante destacar que el acceso a variables estáticas mutables no es seguro por defecto y requiere el uso de bloques `unsafe`. 67 | 68 | ```rust 69 | static mut COUNTER: u32 = 0; 70 | 71 | unsafe { 72 | COUNTER += 1; 73 | } 74 | ``` 75 | 76 | > El uso de `unsafe` indica al compilador que el programador asegura manualmente que el acceso concurrente está controlado, lo que puede llevar a errores si no se maneja adecuadamente. 77 | 78 | ## Almacenamiento en Memoria 79 | 80 | ### Constantes 81 | 82 | Las constantes, debido a su naturaleza inmutable y evaluada en tiempo de compilación, generalmente se almacenan directamente en el segmento de texto del binario, que es una sección de solo lectura de la memoria. Esto permite un acceso rápido y eficiente a estos valores en tiempo de ejecución. 83 | 84 | ### Variables Estáticas 85 | 86 | Las variables estáticas, tanto mutables como inmutables, se almacenan en el segmento de datos estáticos del binario. Este segmento es parte de la memoria que se mantiene durante toda la ejecución del programa, lo que significa que las variables estáticas existen durante toda la vida del programa. 87 | 88 | ## Implicancias de Uso 89 | 90 | ### Seguridad y Rendimiento 91 | 92 | El uso de constantes es muy seguro y eficiente en Rust debido a su evaluación en tiempo de compilación y su almacenamiento en el segmento de solo lectura. Esto reduce el riesgo de errores y mejora el rendimiento. 93 | 94 | Las variables estáticas, aunque útiles para ciertos casos, deben usarse con precaución, especialmente las mutables, debido a los posibles problemas de concurrencia y seguridad que pueden surgir. El uso de `unsafe` para acceder a variables estáticas mutables subraya la necesidad de manejar estos accesos con extremo cuidado. 95 | 96 | ### Mejores Prácticas 97 | 98 | - **Prefiere constantes sobre variables estáticas siempre que sea posible**: Las constantes son más seguras y más eficientes. 99 | - **Minimiza el uso de variables estáticas mutables**: Si necesitas mutabilidad global, considera otras alternativas como el uso de estructuras de datos seguras para concurrencia (`Mutex`, `RwLock`, etc.). 100 | - **Aprovecha la evaluación en tiempo de compilación**: Utiliza constantes para valores que pueden ser computados en tiempo de compilación para aprovechar al máximo las optimizaciones del compilador. 101 | 102 | ## Conclusión 103 | 104 | Entender la diferencia entre constantes y variables estáticas en Rust, así como su almacenamiento y uso adecuado, es crucial para escribir código eficiente y seguro. Las constantes, con su evaluación en tiempo de compilación, proporcionan una forma poderosa de definir valores inmutables, mientras que las variables estáticas ofrecen una solución para la persistencia de datos a nivel global, aunque con ciertas advertencias de uso. 105 | 106 | Rust nos ofrece herramientas poderosas y flexibles para manejar inmutabilidad y persistencia de datos, y aprender a usarlas correctamente es esencial para aprovechar todo el potencial del lenguaje. 107 | -------------------------------------------------------------------------------- /content/2.basic/30.hashmap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'HashMap' 3 | description: 'Explorando HashMap en Rust: Almacenamiento y Manipulación Eficiente de Datos Asociativos' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'medium' 8 | position: 9 | x: 120 10 | y: 600 11 | # width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch08-03-hash-maps' 16 | - name: 'Comprehensive Rust' 17 | english: true 18 | link: 'https://google.github.io/comprehensive-rust/es/std-types/hashmap.html' 19 | - name: 'Documentacion Oficial' 20 | english: true 21 | link: 'https://doc.rust-lang.org/std/collections/struct.HashMap.html' 22 | --- 23 | ## HashMap en Rust: Almacenamiento y Manipulación Eficiente de Datos Asociativos 24 | 25 | En Rust, el tipo `HashMap` es una colección poderosa que permite almacenar pares clave-valor de manera eficiente. Los `HashMap` son ampliamente utilizados cuando se necesita un acceso rápido y eficiente a los datos basados en claves únicas. En este blog post, exploraremos el funcionamiento de los `HashMap` en Rust, cómo se utilizan, su representación en memoria, sus ventajas, y algunos patrones de uso comunes. 26 | 27 | ### ¿Qué es un `HashMap`? 28 | 29 | Un `HashMap` es una colección que almacena pares clave-valor, donde cada clave es única y se asocia con un valor. Este tipo de datos es ideal para situaciones en las que se necesita acceder, insertar o eliminar elementos rápidamente mediante una clave. 30 | 31 | ### Funcionamiento en Memoria 32 | 33 | Internamente, un `HashMap` se implementa utilizando una tabla hash. La clave se pasa a través de una función hash para determinar la ubicación en la tabla donde se almacenará el valor correspondiente. Esto permite operaciones de búsqueda, inserción y eliminación muy eficientes. 34 | 35 | #### Gráfico: Representación en Memoria de un `HashMap` 36 | 37 | ```plaintext 38 | HashMap: 39 | +-------+------+-------+------+ 40 | | Clave | Hash | Índice | Valor | 41 | +-------+------+-------+------+ 42 | | "a" | 1234 | 0 | 10 | 43 | | "b" | 5678 | 1 | 20 | 44 | | "c" | 9101 | 2 | 30 | 45 | +-------+------+-------+------+ 46 | ``` 47 | 48 | ### Creación y Uso de `HashMap` 49 | 50 | Crear y manipular un `HashMap` en Rust es sencillo. A continuación, se muestran algunos ejemplos básicos: 51 | 52 | #### Ejemplo 1: Creación y Adición de Elementos 53 | 54 | ```rust 55 | use std::collections::HashMap; 56 | 57 | fn main() { 58 | let mut mapa = HashMap::new(); // Crear un nuevo HashMap vacío 59 | mapa.insert("clave1", 10); // Insertar pares clave-valor 60 | mapa.insert("clave2", 20); 61 | mapa.insert("clave3", 30); 62 | 63 | println!("{:?}", mapa); // Output: {"clave1": 10, "clave2": 20, "clave3": 30} 64 | } 65 | ``` 66 | 67 | #### Ejemplo 2: Acceso a Elementos 68 | 69 | ```rust 70 | use std::collections::HashMap; 71 | 72 | fn main() { 73 | let mut mapa = HashMap::new(); 74 | mapa.insert("clave1", 10); 75 | mapa.insert("clave2", 20); 76 | 77 | if let Some(valor) = mapa.get("clave1") { 78 | println!("El valor para 'clave1' es: {}", valor); // Output: El valor para 'clave1' es: 10 79 | } 80 | } 81 | ``` 82 | 83 | #### Ejemplo 3: Iteración sobre un `HashMap` 84 | 85 | ```rust 86 | use std::collections::HashMap; 87 | 88 | fn main() { 89 | let mut mapa = HashMap::new(); 90 | mapa.insert("clave1", 10); 91 | mapa.insert("clave2", 20); 92 | mapa.insert("clave3", 30); 93 | 94 | for (clave, valor) in &mapa { 95 | println!("Clave: {}, Valor: {}", clave, valor); 96 | } 97 | } 98 | ``` 99 | 100 | ### Ventajas de Usar `HashMap` 101 | 102 | - **Acceso Rápido:** Los `HashMap` proporcionan un acceso constante promedio O(1) a los valores mediante sus claves, lo que los hace muy eficientes para búsquedas rápidas. 103 | - **Flexibilidad:** Permiten almacenar pares clave-valor de cualquier tipo, siempre que las claves implementen las traits `Eq` y `Hash`. 104 | - **Versatilidad:** Son útiles en una amplia gama de aplicaciones, desde bases de datos simples hasta sistemas de caché y configuraciones. 105 | 106 | ### Métodos Comunes de `HashMap` 107 | 108 | - `insert()`: Añade un par clave-valor al `HashMap`. 109 | - `get()`: Recupera un valor asociado con una clave específica. 110 | - `remove()`: Elimina un par clave-valor del `HashMap`. 111 | - `contains_key()`: Verifica si una clave está presente en el `HashMap`. 112 | - `entry()`: Proporciona una manera eficiente de insertar o modificar un valor basado en una clave. 113 | 114 | #### Ejemplo: Métodos Comunes 115 | 116 | ```rust 117 | use std::collections::HashMap; 118 | 119 | fn main() { 120 | let mut mapa = HashMap::new(); 121 | mapa.insert("clave1", 10); 122 | 123 | // Verificar si una clave existe 124 | if mapa.contains_key("clave1") { 125 | println!("'clave1' existe en el mapa."); 126 | } 127 | 128 | // Uso de entry para insertar o modificar un valor 129 | mapa.entry("clave2").or_insert(20); 130 | mapa.entry("clave1").and_modify(|v| *v += 10); 131 | 132 | println!("{:?}", mapa); // Output: {"clave1": 20, "clave2": 20} 133 | } 134 | ``` 135 | 136 | ### Diferencia con Otros Tipos de Colección 137 | 138 | A diferencia de los vectores (`Vec`), que almacenan elementos en un orden específico y permiten el acceso mediante índices, los `HashMap` almacenan elementos en base a claves únicas y permiten el acceso mediante estas claves. Esto los hace más adecuados para aplicaciones donde se necesita acceso rápido a valores específicos basados en claves, en lugar de operaciones de secuencia ordenada. 139 | 140 | ### Coste Computacional de `HashMap` 141 | 142 | El uso de `HashMap` implica un coste computacional para calcular las funciones hash y manejar posibles colisiones. Sin embargo, Rust optimiza estas operaciones para mantener el acceso a los datos lo más eficiente posible. La mayoría de las operaciones tienen un coste promedio de O(1), lo que las hace muy eficientes en la práctica. 143 | 144 | ### Conclusión 145 | 146 | `HashMap` es una herramienta esencial en Rust para trabajar con colecciones de datos asociativos. Su flexibilidad, eficiencia y compatibilidad con las claves únicas lo hacen adecuado para una amplia gama de aplicaciones. Al comprender cómo funciona `HashMap` en memoria, sus ventajas y cómo utilizar sus métodos comunes, los desarrolladores pueden aprovechar al máximo las capacidades de Rust para manejar datos de manera efectiva y segura. 147 | -------------------------------------------------------------------------------- /content/2.basic/4.shadowing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Shadowing' 3 | description: 'Shadowing de Variables en Rust: Concepto, Casos de Uso y Gestión en Memoria' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 320 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-01-variables-and-mutability#shadowing' 16 | - name: 'Comprehensive Rust' 17 | english: false 18 | link: 'https://google.github.io/comprehensive-rust/es/control-flow-basics/blocks-and-scopes.html?highlight=shado#%C3%81mbitos-y--shadowing' 19 | --- 20 | # Shadowing de Variables en Rust: Concepto, Casos de Uso y Gestión en Memoria 21 | 22 | Rust, conocido por su seguridad y eficiencia, también ofrece flexibilidad en la gestión de variables a través de una característica llamada **shadowing**. El shadowing permite declarar una nueva variable con el mismo nombre que una anterior en el mismo contexto, "sombreando" la variable original. En este artículo, exploraremos qué es el shadowing, cuándo y cómo se utiliza, y cómo se gestiona en memoria. 23 | 24 | ## ¿Qué es el Shadowing? 25 | 26 | El shadowing en Rust ocurre cuando una nueva variable se declara con el mismo nombre que una anterior en el mismo contexto. Esto no debe confundirse con la mutabilidad; más bien, se trata de crear una nueva variable que oculta a la anterior, de alli el nombre `shadowing` ya que sombreamos la variable anterior. 27 | 28 | ```rust 29 | fn main() { 30 | let x = 5; 31 | let x = x + 1; 32 | { 33 | let x = x * 2; 34 | println!("El valor de x en el contexto interno es: {}", x); // 12 35 | } 36 | println!("El valor de x en el contexto externo es: {}", x); // 6 37 | } 38 | ``` 39 | 40 | En este ejemplo, la variable `x` es "sombreada" dos veces: una vez en el contexto principal y otra dentro del contexto interno. Cada declaración de `x` crea una nueva variable, dejando intactas las versiones anteriores dentro de su propio contexto. 41 | 42 | ## Casos de Uso del Shadowing 43 | 44 | ### Refinamiento de Tipos 45 | 46 | Uno de los usos comunes del shadowing es cambiar el tipo de una variable en una nueva declaración. 47 | 48 | ```rust 49 | let spaces = " "; 50 | let spaces = spaces.len(); 51 | ``` 52 | 53 | Aquí, `spaces` primero es una cadena de texto, y luego se sombrea con una variable de tipo `usize`, que representa la longitud de la cadena. 54 | 55 | ### Transformaciones Intermedias 56 | 57 | El shadowing es útil para aplicar transformaciones intermedias a una variable sin necesitar nombres adicionales. 58 | 59 | ```rust 60 | let price = 100; 61 | let price = price * 2; 62 | let price = price - 10; 63 | ``` 64 | 65 | En este ejemplo, `price` se actualiza en cada paso sin la necesidad de crear nuevas variables como `price1`, `price2`, etc. 66 | 67 | ### Evitar la Mutabilidad 68 | 69 | El shadowing puede evitar la necesidad de usar variables mutables, lo cual es preferido en Rust por razones de seguridad. 70 | 71 | ```rust 72 | let mut count = 1; 73 | count += 1; 74 | ``` 75 | 76 | se puede escribir como: 77 | 78 | ```rust 79 | let count = 1; 80 | let count = count + 1; 81 | ``` 82 | 83 | ## Interpretación en Memoria 84 | 85 | Cada vez que una variable es sombreada, Rust crea una nueva variable en el stack en lugar de modificar la existente. Esto implica que cada versión sombreada de la variable tiene su propia ubicación en memoria. 86 | 87 | > Esto es importante a tener en cuenta ya que no estamos reutilizando el espacio de memoria anteriormente reservado. 88 | 89 | ### Gestión de Memoria 90 | 91 | 1. **Contexto Principal**: Cuando `x` se declara por primera vez en el contexto principal, se asigna memoria en el stack. 92 | 2. **Shadowing en el Mismo Contexto**: Al sombrear `x` en el mismo contexto, se asigna una nueva ubicación en memoria para la nueva `x`, dejando intacta la primera. 93 | 3. **Contexto Interno**: En un contexto interno, otra nueva `x` se crea en el stack y se elimina al salir del contexto. 94 | 95 | Este comportamiento asegura que cada versión de la variable mantenga su valor original dentro de su propio contexto, y que las variables anteriores no sean modificadas accidentalmente. 96 | 97 | ## Implicaciones y Mejores Prácticas 98 | 99 | ### Ventajas del Shadowing 100 | 101 | - **Inmutabilidad**: Permite trabajar con variables inmutables, mejorando la seguridad y legibilidad del código. 102 | - **Claridad**: Facilita la actualización de variables sin introducir nombres adicionales, lo cual puede hacer el código más claro y conciso. 103 | - **Tipo Seguro**: Permite cambiar tipos de variables de manera segura y explícita. 104 | 105 | ### Precauciones 106 | 107 | - **Confusión Potencial**: Un uso excesivo puede llevar a confusión sobre cuál es la variable actual. 108 | - **Uso Intencionado**: Debe ser utilizado de manera intencionada y clara para mejorar la legibilidad y mantenimiento del código. 109 | 110 | ## Conclusión 111 | 112 | El shadowing de variables en Rust es una característica poderosa que permite redefinir variables dentro del mismo contexto, proporcionando flexibilidad sin sacrificar la seguridad. Al comprender cómo funciona el shadowing y cómo se gestionan las variables en memoria, los desarrolladores pueden aprovechar esta herramienta para escribir código más limpio y eficiente. Utilizado correctamente, el shadowing puede simplificar transformaciones de variables y mejorar la inmutabilidad del código, haciendo que los programas en Rust sean más seguros y fáciles de mantener. 113 | -------------------------------------------------------------------------------- /content/2.basic/5.control-flow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Control de Flujo' 3 | description: 'Control de Flujo en Rust, como usar if, if-else, match, loop, while y for' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 360 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch03-05-control-flow' 16 | - name: 'Comprehensive Rust' 17 | english: false 18 | link: 'https://google.github.io/comprehensive-rust/es/control-flow-basics.html' 19 | --- 20 | # Control de Flujo en Rust: if, if-else, match, loop, while y for 21 | 22 | Rust es un lenguaje de programación que combina seguridad y rendimiento con una sintaxis clara y poderosa. El control de flujo en Rust se maneja a través de estructuras conocidas como `if`, `if-else`, `match`, y diversos tipos de bucles (`loop`, `while`, `for`). En este artículo, exploraremos cada una de estas construcciones y cómo se utilizan para controlar el flujo de ejecución en un programa Rust, incluyendo los `named loops`. 23 | 24 | ## Condicionales: if y if-else 25 | 26 | Las estructuras condicionales en Rust se manejan mediante `if` y `if-else`. Estas permiten ejecutar bloques de código basados en condiciones booleanas. 27 | 28 | ### if 29 | 30 | La declaración `if` se utiliza para ejecutar un bloque de código solo si una condición es verdadera. 31 | 32 | ```rust 33 | let number = 7; 34 | 35 | if number < 10 { 36 | println!("El número es menor que 10"); 37 | } 38 | ``` 39 | 40 | En este ejemplo, el mensaje se imprimirá porque la condición `number < 10` es verdadera. 41 | 42 | ### if-else 43 | 44 | La declaración `if-else` se utiliza cuando se desea ejecutar un bloque de código si la condición es verdadera y otro bloque si es falsa. 45 | 46 | ```rust 47 | let number = 7; 48 | 49 | if number < 10 { 50 | println!("El número es menor que 10"); 51 | } else { 52 | println!("El número es mayor o igual a 10"); 53 | } 54 | ``` 55 | 56 | Aquí, se imprime el primer mensaje porque la condición es verdadera. 57 | 58 | ### if-else if-else 59 | 60 | Para manejar múltiples condiciones, se puede usar `else if`. 61 | 62 | ```rust 63 | let number = 15; 64 | 65 | if number < 10 { 66 | println!("El número es menor que 10"); 67 | } else if number < 20 { 68 | println!("El número está entre 10 y 19"); 69 | } else { 70 | println!("El número es 20 o mayor"); 71 | } 72 | ``` 73 | 74 | Este ejemplo imprimirá el segundo mensaje porque la condición `number < 20` es verdadera. 75 | 76 | ## match 77 | 78 | La declaración `match` en Rust es una potente estructura de control de flujo que permite manejar múltiples condiciones de manera más clara y concisa que múltiples `if-else`. 79 | 80 | ```rust 81 | let number = 3; 82 | 83 | match number { 84 | 1 => println!("Uno"), 85 | 2 => println!("Dos"), 86 | 3 => println!("Tres"), 87 | _ => println!("Otro número"), 88 | } 89 | ``` 90 | 91 | En este ejemplo, se imprimirá "Tres" porque `number` es igual a 3. El carácter `_` actúa como un comodín que coincide con cualquier valor no especificado anteriormente. 92 | 93 | ## Bucles 94 | 95 | Rust proporciona varias maneras de repetir bloques de código: `loop`, `while`, y `for`. 96 | 97 | ### loop 98 | 99 | El bucle `loop` ejecuta un bloque de código indefinidamente hasta que se encuentre una declaración `break`. 100 | 101 | ```rust 102 | let mut counter = 0; 103 | 104 | loop { 105 | counter += 1; 106 | if counter == 10 { 107 | break; 108 | } 109 | } 110 | 111 | println!("El contador llegó a: {}", counter); 112 | ``` 113 | 114 | Este bucle incrementa `counter` hasta que alcanza 10, momento en el cual se sale del bucle con `break`. 115 | 116 | #### Named Loops 117 | 118 | Rust permite etiquetar bucles usando `'label_name` para poder referirse a ellos específicamente, lo que es útil para romper o continuar bucles externos desde un bucle interno. 119 | 120 | ```rust 121 | let mut count = 0; 122 | 'outer: loop { 123 | let mut remaining = 10; 124 | 125 | loop { 126 | if remaining == 9 { 127 | break; 128 | } 129 | if count == 2 { 130 | break 'outer; 131 | } 132 | remaining -= 1; 133 | } 134 | 135 | count += 1; 136 | } 137 | 138 | println!("Count terminó en: {}", count); 139 | ``` 140 | 141 | En este ejemplo, `break 'outer` rompe el bucle etiquetado como `'outer`, terminando ambos bucles cuando `count` es igual a 2. 142 | 143 | ### while 144 | 145 | El bucle `while` ejecuta un bloque de código mientras una condición sea verdadera. 146 | 147 | ```rust 148 | let mut number = 3; 149 | 150 | while number != 0 { 151 | println!("{}!", number); 152 | number -= 1; 153 | } 154 | 155 | println!("¡Despegue!"); 156 | ``` 157 | 158 | En este ejemplo, el bucle `while` decrece `number` hasta que llega a 0, imprimiendo cada número en el proceso. 159 | 160 | ### for 161 | 162 | El bucle `for` en Rust se utiliza para iterar sobre una colección, como un rango o una lista. 163 | 164 | #### Iterando sobre un rango 165 | 166 | ```rust 167 | for number in 1..4 { 168 | println!("El número es: {}", number); 169 | } 170 | ``` 171 | 172 | Este bucle imprimirá "El número es: 1", "El número es: 2" y "El número es: 3". El rango `1..4` incluye 1 pero excluye 4. 173 | 174 | #### Iterando sobre una colección 175 | 176 | ```rust 177 | let array = [10, 20, 30, 40, 50]; 178 | 179 | for element in array.iter() { 180 | println!("El valor es: {}", element); 181 | } 182 | ``` 183 | 184 | Aquí, el bucle `for` itera sobre los elementos del arreglo `array`, imprimiendo cada uno de ellos. 185 | 186 | ## Conclusión 187 | 188 | El control de flujo en Rust es versátil y poderoso, permitiendo a los desarrolladores manejar condiciones y bucles de manera clara y eficiente. Las estructuras `if`, `if-else` y `match` facilitan la toma de decisiones, mientras que los bucles `loop`, `while` y `for` permiten la repetición de bloques de código con gran flexibilidad. Los named loops añaden una capa adicional de control para manejar bucles anidados de manera más precisa. Comprender estas construcciones es esencial para escribir programas Rust robustos y eficientes. 189 | -------------------------------------------------------------------------------- /content/2.basic/7.pattern-matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Pattern Matching/Desestruct' 3 | description: 'Entendiendo Pattern Matching y Desestructuración en Rust: Exhaustividad y Seguridad' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 440 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch06-02-match' 16 | - name: 'Comprehensive Rust' 17 | english: false 18 | link: 'https://google.github.io/comprehensive-rust/es/pattern-matching/destructuring.html' 19 | --- 20 | ### Entendiendo Pattern Matching y Desestructuración en Rust: Exhaustividad y Seguridad 21 | 22 | Rust es un lenguaje de programación que combina eficiencia y seguridad sin sacrificar el control sobre los detalles de bajo nivel. Una de las características más poderosas de Rust es su sistema de pattern matching y desestructuración. Estas herramientas permiten escribir código más expresivo y manejable, garantizando al mismo tiempo la exhaustividad en el control de flujo. En este blog post, exploraremos cómo funcionan el pattern matching y la desestructuración en Rust, así como su exhaustividad y beneficios. 23 | 24 | #### ¿Qué es Pattern Matching? 25 | 26 | Pattern matching es una característica que permite comparar una estructura de datos contra varios patrones y, si hay una coincidencia, descomponer la estructura en sus componentes. Rust utiliza la palabra clave `match` para pattern matching, lo que hace que el código sea más legible y manejable. 27 | 28 | ##### Ejemplo Básico 29 | 30 | ```rust 31 | enum Color { 32 | Red, 33 | Green, 34 | Blue, 35 | } 36 | 37 | fn main() { 38 | let color = Color::Green; 39 | 40 | match color { 41 | Color::Red => println!("Color rojo"), 42 | Color::Green => println!("Color verde"), 43 | Color::Blue => println!("Color azul"), 44 | } 45 | } 46 | ``` 47 | 48 | En este ejemplo, `match` se utiliza para determinar el valor de la variable `color` y ejecutar el código correspondiente a cada variante del enum `Color`. 49 | 50 | #### Exhaustividad en Pattern Matching 51 | 52 | Una de las características más importantes del pattern matching en Rust es su exhaustividad. Esto significa que todos los casos posibles deben ser manejados, lo que garantiza que no se pase por alto ningún caso. Si se olvida un caso, el compilador emitirá un error, asegurando que se aborden todas las posibilidades. 53 | 54 | ##### Ejemplo de Exhaustividad 55 | 56 | ```rust 57 | enum Animal { 58 | Perro, 59 | Gato, 60 | } 61 | 62 | fn main() { 63 | let mascota = Animal::Perro; 64 | 65 | match mascota { 66 | Animal::Perro => println!("Es un perro"), 67 | Animal::Gato => println!("Es un gato"), 68 | // Falta un caso: Rust emitirá un error si se agrega una variante nueva sin manejarla 69 | } 70 | } 71 | ``` 72 | 73 | En este ejemplo, si se añadiera una nueva variante al enum `Animal`, como `Animal::Pez`, el compilador emitiría un error indicando que el match no es exhaustivo, obligando al desarrollador a manejar el nuevo caso. 74 | 75 | #### Desestructuración 76 | 77 | La desestructuración permite dividir una estructura de datos en sus componentes individuales. Rust facilita la desestructuración de arrays, tuplas, structs y enums, lo cual es útil para trabajar con datos complejos. 78 | 79 | ##### Desestructuración de Tuplas 80 | 81 | ```rust 82 | fn main() { 83 | let tupla = (1, "hola", 3.5); 84 | 85 | let (a, b, c) = tupla; 86 | 87 | println!("a: {}, b: {}, c: {}", a, b, c); 88 | } 89 | ``` 90 | 91 | En este ejemplo, la tupla `(1, "hola", 3.5)` se desestructura en las variables `a`, `b` y `c`. 92 | 93 | ##### Desestructuración de Structs 94 | 95 | ```rust 96 | struct Punto { 97 | x: i32, 98 | y: i32, 99 | } 100 | 101 | fn main() { 102 | let punto = Punto { x: 5, y: 10 }; 103 | 104 | let Punto { x, y } = punto; 105 | 106 | println!("x: {}, y: {}", x, y); 107 | } 108 | ``` 109 | 110 | Aquí, el struct `Punto` se desestructura en sus campos `x` e `y`. 111 | 112 | #### Uso Avanzado de Pattern Matching 113 | 114 | Pattern matching en Rust no se limita a estructuras de datos simples, sino que puede manejar patrones complejos, incluyendo guardas, valores anidados y opciones. 115 | 116 | ##### Match con Guardas 117 | 118 | ```rust 119 | fn main() { 120 | let numero = Some(4); 121 | 122 | match numero { 123 | Some(x) if x < 5 => println!("Menos que 5: {}", x), 124 | Some(x) => println!("Mayor o igual a 5: {}", x), 125 | None => println!("Sin valor"), 126 | } 127 | } 128 | ``` 129 | 130 | Las guardas (`if x < 5`) permiten añadir condiciones adicionales a los patrones. 131 | 132 | ##### Patrones Anidados 133 | 134 | ```rust 135 | enum Mensaje { 136 | Saludo { id: i32, contenido: String }, 137 | } 138 | 139 | fn main() { 140 | let mensaje = Mensaje::Saludo { 141 | id: 1, 142 | contenido: String::from("Hola"), 143 | }; 144 | 145 | match mensaje { 146 | Mensaje::Saludo { id, contenido } => { 147 | println!("ID: {}, Contenido: {}", id, contenido); 148 | } 149 | } 150 | } 151 | ``` 152 | 153 | Aquí se desestructura un enum con campos nombrados, extrayendo `id` y `contenido`. 154 | 155 | #### Pattern Matching en Funciones 156 | 157 | Pattern matching también se puede usar directamente en las firmas de las funciones para hacer el código más limpio. 158 | 159 | ```rust 160 | fn procesar_punto(Punto { x, y }: Punto) { 161 | println!("x: {}, y: {}", x, y); 162 | } 163 | 164 | fn main() { 165 | let punto = Punto { x: 5, y: 10 }; 166 | procesar_punto(punto); 167 | } 168 | ``` 169 | 170 | En este ejemplo, el patrón se aplica directamente en los parámetros de la función `procesar_punto`. 171 | 172 | #### Conclusión 173 | 174 | El pattern matching y la desestructuración en Rust son herramientas poderosas que permiten manejar estructuras de datos complejas de manera más expresiva y eficiente. La exhaustividad del pattern matching asegura que todos los posibles casos se manejen adecuadamente, lo que contribuye a la seguridad y robustez del código. Comprender y utilizar estas características efectivamente puede mejorar significativamente la calidad y la mantenibilidad del código en Rust. 175 | -------------------------------------------------------------------------------- /content/2.basic/8.ownership-borrowing.yml: -------------------------------------------------------------------------------- 1 | title: 'Ownership y Borrowing' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: -700 8 | y: 520 9 | width: 320 10 | align: 'center' 11 | sourcePosition: 12 | none: 'top' 13 | targetPosition: 14 | basic: 'right' 15 | -------------------------------------------------------------------------------- /content/2.basic/9.ownership-borrowing-concept.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Concepto Basico' 3 | description: 'Entendiendo el Paradigma de Ownership y Borrowing en Rust' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: -700 10 | y: 560 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch04-00-understanding-ownership' 16 | - name: 'Comprehensive Rust' 17 | english: false 18 | link: 'https://google.github.io/comprehensive-rust/es/borrowing.html' 19 | --- 20 | ## Entendiendo el Paradigma de Ownership y Borrowing en Rust 21 | 22 | ### Introducción 23 | 24 | Rust es un lenguaje de programación que ha ganado mucha popularidad por su enfoque en la seguridad y el rendimiento. Uno de los conceptos más revolucionarios y distintivos de Rust es su sistema de **ownership (propiedad)** y **borrowing (préstamo)**. Estos conceptos no solo representan un cambio de paradigma en la gestión de memoria y recursos, sino que también ofrecen garantías de seguridad que se validan en tiempo de compilación, eliminando muchos errores comunes en lenguajes como C y C++. 25 | 26 | ### Ownership: Propiedad y Control Absoluto 27 | 28 | En Rust, cada valor tiene un único propietario, una variable que se encarga de gestionar ese valor. Cuando el propietario sale de su alcance (scope), el valor es automáticamente liberado. Este mecanismo se conoce como **RAII (Resource Acquisition Is Initialization)**, que asegura que los recursos se liberen correctamente sin necesidad de una intervención explícita del programador. 29 | 30 | Ejemplo básico: 31 | ```rust 32 | fn main() { 33 | let x = String::from("Hello"); 34 | println!("{}", x); // x es el propietario de la cadena "Hello" 35 | } // x sale del alcance y "Hello" es liberada automáticamente 36 | ``` 37 | 38 | ### Borrowing: Préstamo y Compartición Controlada 39 | 40 | A veces es necesario compartir datos entre diferentes partes del programa sin transferir la propiedad. Aquí es donde entra el concepto de **borrowing**. En Rust, se puede pedir prestado un valor de dos formas: **prestamos inmutables** y **prestamos mutables**. 41 | 42 | - **Préstamos Inmutables:** Permiten múltiples accesos de solo lectura. 43 | ```rust 44 | fn main() { 45 | let s = String::from("Hello"); 46 | let len = calculate_length(&s); // Se presta de manera inmutable 47 | println!("La longitud de '{}' es {}.", s, len); 48 | } 49 | 50 | fn calculate_length(s: &String) -> usize { 51 | s.len() // Solo se permite leer s 52 | } 53 | ``` 54 | 55 | - **Préstamos Mutables:** Permiten un único acceso de lectura/escritura. 56 | ```rust 57 | fn main() { 58 | let mut s = String::from("Hello"); 59 | change(&mut s); // Se presta de manera mutable 60 | println!("{}", s); 61 | } 62 | 63 | fn change(s: &mut String) { 64 | s.push_str(", world"); 65 | } 66 | ``` 67 | 68 | ### Cambio de Paradigma y Pensamiento 69 | 70 | El sistema de ownership y borrowing de Rust introduce un cambio significativo en la manera de pensar y escribir código. A diferencia de otros lenguajes donde la gestión de memoria se realiza manualmente o mediante un recolector de basura (garbage collector), Rust hace estas validaciones en tiempo de compilación. Esto significa que muchos errores comunes, como los accesos a memoria no válida, fugas de memoria y condiciones de carrera, se detectan antes de que el programa se ejecute. 71 | 72 | ### Beneficios de las Validaciones en Compilación 73 | 74 | 1. **Seguridad en Tiempo de Compilación:** El compilador de Rust garantiza que todas las reglas de ownership y borrowing se cumplan antes de que el código se ejecute. Esto elimina una gran clase de errores de programación que en otros lenguajes solo se detectarían en tiempo de ejecución. 75 | 76 | 2. **Eliminación de Fugas de Memoria:** Al asegurar que cada recurso tiene un único propietario responsable de su liberación, Rust previene las fugas de memoria. 77 | 78 | 3. **Prevención de Condiciones de Carrera:** Al restringir los accesos concurrentes a los datos mediante préstamos mutables, Rust evita las condiciones de carrera, un problema común en la programación concurrente. 79 | 80 | 4. **Rendimiento Predecible:** Sin la sobrecarga de un recolector de basura, Rust puede ofrecer un rendimiento más predecible y eficiente, crucial en sistemas de tiempo real y aplicaciones de alto rendimiento. 81 | 82 | ### Conclusión 83 | 84 | El sistema de ownership y borrowing de Rust no es solo una característica más; es un cambio de paradigma que redefine cómo pensamos y manejamos la memoria y los recursos en nuestros programas. Aunque puede requerir un tiempo de adaptación, las garantías y beneficios que ofrece en términos de seguridad y rendimiento hacen que valga la pena el esfuerzo. Rust demuestra que es posible tener un lenguaje que sea tanto seguro como de alto rendimiento, y lo hace mediante la validación de sus estrictas reglas en tiempo de compilación. 85 | -------------------------------------------------------------------------------- /content/3.error-handling/1.option.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Options' 3 | description: 'Option es una enumeración en Rust que se utiliza para representar valores que pueden o no estar presentes' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'start' 8 | position: 9 | x: 320 10 | y: 580 11 | width: 320 12 | externalLinks: 13 | - name: 'Libro Oficial' 14 | english: false 15 | link: 'https://book.rustlang-es.org/ch06-01-defining-an-enum' 16 | - name: 'Comprehensive Rust' 17 | english: false 18 | link: 'https://google.github.io/comprehensive-rust/es/std-types/option.html' 19 | - name: 'Documentacion Oficial' 20 | english: true 21 | link: 'https://doc.rust-lang.org/stable/std/option' 22 | - name: '¿Cómo almacena Rust los enum en memoria?' 23 | english: false 24 | link: 'https://blog.rustlang-es.org/articles/como-almacena-rust-los-enum-en-memoria' 25 | --- 26 | ## Entendiendo el Tipo `Option` en Rust: Seguridad y Ausencia de Valores Nulos 27 | 28 | En Rust, el tipo `Option` es una herramienta fundamental que permite manejar de forma segura la ausencia de un valor sin recurrir al temido null. En lugar de utilizar valores nulos que pueden llevar a errores inesperados, Rust introduce `Option`, que garantiza que el manejo de valores opcionales sea explícito y seguro. 29 | 30 | ### ¿Qué es un `Option`? 31 | 32 | `Option` es un enum predefinido en Rust que puede tomar dos valores: 33 | 34 | ```rust 35 | enum Option { 36 | Some(T), 37 | None, 38 | } 39 | ``` 40 | 41 | - `Some(T)` indica que hay un valor presente. 42 | - `None` representa la ausencia de un valor. 43 | 44 | ### Funciones Comunes para Trabajar con `Option` 45 | 46 | Rust ofrece múltiples funciones para manipular opciones de forma segura: 47 | 48 | - **is_some() e is_none():** Verifican si un `Option` contiene un valor o no. 49 | 50 | ```rust 51 | let maybe_value: Option = Some(5); 52 | assert!(maybe_value.is_some()); 53 | 54 | let no_value: Option = None; 55 | assert!(no_value.is_none()); 56 | ``` 57 | 58 | - **unwrap() y expect():** Extraen el valor del `Option`, pero si es `None`, `unwrap()` causará un pánico. `expect()` permite proporcionar un mensaje de error personalizado. 59 | 60 | ```rust 61 | let value = maybe_value.unwrap(); // Devuelve 5 o causa un pánico si es None. 62 | ``` 63 | 64 | - **map():** Permite aplicar una función al valor dentro de un `Option`, devolviendo un nuevo `Option`. 65 | 66 | ```rust 67 | let maybe_value: Option = Some(5); 68 | let maybe_double = maybe_value.map(|x| x * 2); 69 | assert_eq!(maybe_double, Some(10)); 70 | ``` 71 | 72 | - **and(), or() y xor():** Estas funciones permiten combinar opciones de manera segura. 73 | 74 | ```rust 75 | let a: Option = Some(2); 76 | let b: Option = Some(3); 77 | let c: Option = None; 78 | 79 | assert_eq!(a.and(b), Some(3)); // Devuelve Some(3) 80 | assert_eq!(a.or(c), Some(2)); // Devuelve Some(2) 81 | assert_eq!(c.or(a), Some(2)); // Devuelve Some(2) 82 | ``` 83 | 84 | ### Pattern Matching con `Option` 85 | 86 | El pattern matching es una forma común de interactuar con `Option`. Permite realizar acciones diferentes según el estado de la opción (si es `Some` o `None`): 87 | 88 | ```rust 89 | let maybe_number = Some(10); 90 | 91 | match maybe_number { 92 | Some(value) => println!("El valor es: {}", value), 93 | None => println!("No hay valor"), 94 | } 95 | ``` 96 | 97 | ### Interactuar con Múltiples `Option` 98 | 99 | Cuando trabajas con múltiples `Option`, puedes combinarlas utilizando combinadores como `and_then()` o emplear pattern matching para manejar múltiples opciones simultáneamente: 100 | 101 | ```rust 102 | let x: Option = Some(2); 103 | let y: Option = Some(3); 104 | 105 | let result = x.and_then(|x_val| { 106 | y.map(|y_val| x_val + y_val) 107 | }); 108 | 109 | assert_eq!(result, Some(5)); 110 | ``` 111 | 112 | ### Funcionamiento en Memoria 113 | 114 | Rust optimiza la representación en memoria de `Option`. Si `T` es un tipo que puede tener un valor que represente la ausencia de datos (por ejemplo, punteros o números enteros), Rust puede usar una optimización para no consumir espacio adicional para `Option`. De este modo, `Option` es tan eficiente en memoria como el propio tipo base. 115 | 116 | ### Conclusión 117 | 118 | `Option` es un poderoso reemplazo para los valores nulos, brindando seguridad y claridad al código. Al ser un enum, proporciona flexibilidad y un control robusto sobre situaciones donde un valor puede o no estar presente. Al utilizar funciones como `map()`, `unwrap()`, y combinadores, puedes manejar opciones de forma elegante y segura, mientras el pattern matching te permite gestionar fácilmente las variantes de `Option` según tus necesidades. 119 | 120 | Rust garantiza que al trabajar con `Option`, la ausencia de un valor siempre se trate de manera explícita, evitando así una de las fuentes más comunes de errores en otros lenguajes de programación. 121 | -------------------------------------------------------------------------------- /content/3.error-handling/index.yml: -------------------------------------------------------------------------------- 1 | title: 'Manejo de Errores' 2 | description: '' 3 | draft: true 4 | data: 5 | type: 'custom' 6 | topicLevel: 'medium' 7 | position: 8 | x: 390 9 | y: 700 10 | sourcePosition: 11 | basic: 'left' 12 | targetPosition: 13 | result: 'top' 14 | cargo: 'bottom' 15 | propagation-operator: 'right' 16 | -------------------------------------------------------------------------------- /content/5.traits/3.integrated.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Traits Integrados" 3 | description: "Entendiendo los Traits Más Importantes en Rust" 4 | draft: true 5 | data: 6 | type: "custom" 7 | topicLevel: "start" 8 | position: 9 | x: 400 10 | y: 980 11 | --- 12 | 13 | ### Entendiendo los Traits Más Importantes en Rust 14 | 15 | Rust incluye una rica colección de _traits_ estándar que permiten a los tipos integrarse con el lenguaje y aprovechar comportamientos reutilizables. Estos _traits_ son contratos que los tipos pueden implementar para adquirir funcionalidades específicas. Aquí exploraremos algunos de los más importantes, explicando sus conceptos y cómo aplicarlos. 16 | 17 | ### **1. El Trait `Default`: Valores Predeterminados** 18 | 19 | El trait `Default` define un método para crear un valor predeterminado para un tipo. Esto es especialmente útil al inicializar estructuras grandes con valores predecibles. 20 | 21 | #### Definición 22 | 23 | ```rust 24 | pub trait Default { 25 | fn default() -> Self; 26 | } 27 | ``` 28 | 29 | #### Ejemplo 30 | 31 | ```rust 32 | struct Config { 33 | retries: u32, 34 | verbose: bool, 35 | } 36 | 37 | impl Default for Config { 38 | fn default() -> Self { 39 | Config { 40 | retries: 3, 41 | verbose: false, 42 | } 43 | } 44 | } 45 | 46 | fn main() { 47 | let default_config = Config::default(); 48 | println!("Retries: {}, Verbose: {}", default_config.retries, default_config.verbose); 49 | } 50 | ``` 51 | 52 | ### **2. Los Traits `Clone` y `Copy`: Clonación y Copia** 53 | 54 | - **`Clone`**: Proporciona un método explícito para crear una copia profunda de un valor. 55 | - **`Copy`**: Es una versión implícita y más ligera de clonación, aplicable solo a tipos que se pueden copiar de manera trivial (como números primitivos). 56 | 57 | #### Definición 58 | 59 | ```rust 60 | pub trait Clone { 61 | fn clone(&self) -> Self; 62 | } 63 | 64 | pub trait Copy: Clone {} 65 | ``` 66 | 67 | #### Ejemplo 68 | 69 | ```rust 70 | #[derive(Clone, Copy)] 71 | struct Point { 72 | x: i32, 73 | y: i32, 74 | } 75 | 76 | fn main() { 77 | let p1 = Point { x: 1, y: 2 }; 78 | let p2 = p1; // Copia implícita 79 | let p3 = p1.clone(); // Copia explícita 80 | println!("p1: ({}, {}), p2: ({}, {}), p3: ({}, {})", p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); 81 | } 82 | ``` 83 | 84 | #### Nota sobre `Copy` 85 | 86 | Un tipo que implementa `Copy` no puede tener campos que no lo implementen. 87 | 88 | ### **3. Comparación: `PartialEq` y `Eq`** 89 | 90 | Rust proporciona dos traits para comparar tipos: 91 | 92 | - **`PartialEq`**: Permite verificar si dos valores son iguales (`==`) o diferentes (`!=`). 93 | - **`Eq`**: Es un subtipo de `PartialEq` que asegura que el operador `==` siempre sea reflexivo (es decir, `a == a` siempre es verdadero). 94 | 95 | #### Ejemplo 96 | 97 | ```rust 98 | #[derive(PartialEq, Eq)] 99 | struct User { 100 | id: u32, 101 | name: String, 102 | } 103 | 104 | fn main() { 105 | let user1 = User { id: 1, name: "Alice".to_string() }; 106 | let user2 = User { id: 1, name: "Alice".to_string() }; 107 | 108 | if user1 == user2 { 109 | println!("Users are equal!"); 110 | } 111 | } 112 | ``` 113 | 114 | ### **4. Ordenamiento: `PartialOrd` y `Ord`** 115 | 116 | - **`PartialOrd`**: Permite comparar valores con `<`, `>`, `<=`, `>=`. 117 | - **`Ord`**: Extiende `PartialOrd` para tipos totalmente ordenables. 118 | 119 | #### Ejemplo 120 | 121 | ```rust 122 | #[derive(PartialOrd, Ord, PartialEq, Eq)] 123 | struct Item { 124 | price: u32, 125 | } 126 | 127 | fn main() { 128 | let item1 = Item { price: 10 }; 129 | let item2 = Item { price: 20 }; 130 | 131 | if item1 < item2 { 132 | println!("Item1 is cheaper than Item2"); 133 | } 134 | } 135 | ``` 136 | 137 | ### **5. Traits de Funciones: `Fn`, `FnMut` y `FnOnce`** 138 | 139 | Estos traits representan diferentes tipos de clausuras (_closures_). 140 | 141 | - **`FnOnce`**: Consumo único. 142 | - **`FnMut`**: Clausura mutable. 143 | - **`Fn`**: Clausura inmutable. 144 | 145 | #### Ejemplo 146 | 147 | ```rust 148 | fn execute(operation: F) 149 | where 150 | F: FnOnce(), 151 | { 152 | operation(); 153 | } 154 | 155 | fn main() { 156 | let greeting = "Hello".to_string(); 157 | execute(|| println!("{}", greeting)); // FnOnce 158 | } 159 | ``` 160 | 161 | ### **6. El Trait `Drop`: Limpiar Recursos** 162 | 163 | Permite ejecutar lógica personalizada cuando un valor sale de alcance. 164 | 165 | #### Ejemplo 166 | 167 | ```rust 168 | struct Resource { 169 | name: String, 170 | } 171 | 172 | impl Drop for Resource { 173 | fn drop(&mut self) { 174 | println!("Releasing resource: {}", self.name); 175 | } 176 | } 177 | 178 | fn main() { 179 | let _res = Resource { name: "FileHandle".to_string() }; 180 | } // `_res` se libera aquí automáticamente. 181 | ``` 182 | 183 | ### **7. Iteradores: `Iterator`** 184 | 185 | El trait `Iterator` es fundamental para trabajar con iteraciones. Define cómo un tipo produce una secuencia de valores. 186 | 187 | #### Definición 188 | 189 | ```rust 190 | pub trait Iterator { 191 | type Item; 192 | fn next(&mut self) -> Option; 193 | } 194 | ``` 195 | 196 | #### Ejemplo 197 | 198 | ```rust 199 | struct Counter { 200 | count: u32, 201 | } 202 | 203 | impl Iterator for Counter { 204 | type Item = u32; 205 | 206 | fn next(&mut self) -> Option { 207 | if self.count < 5 { 208 | self.count += 1; 209 | Some(self.count) 210 | } else { 211 | None 212 | } 213 | } 214 | } 215 | 216 | fn main() { 217 | let mut counter = Counter { count: 0 }; 218 | while let Some(value) = counter.next() { 219 | println!("Count: {}", value); 220 | } 221 | } 222 | ``` 223 | 224 | ### **Conclusión** 225 | 226 | Estos traits estándar son esenciales en Rust, ya que forman la base para operaciones comunes como clonación, comparación, iteración y manejo de recursos. Entender cómo y cuándo usarlos es clave para aprovechar todo el potencial de Rust y escribir código más limpio, seguro y eficiente. 227 | -------------------------------------------------------------------------------- /content/6.smart-pointers/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Punteros Inteligentes' 3 | description: '' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'medium' 8 | position: 9 | x: -400 10 | y: 1100 11 | sourcePosition: 12 | traits: 'right' 13 | targetPosition: 14 | concurrency: 'bottom' 15 | --- 16 | # Titulo 17 | -------------------------------------------------------------------------------- /content/7.concurrency/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Concurrencia y Paralelismo' 3 | description: '' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'medium' 8 | position: 9 | x: -300 10 | y: 1400 11 | sourcePosition: 12 | smart-pointers: 'left' 13 | targetPosition: 14 | interop: 'right' 15 | --- 16 | # Titulo 17 | -------------------------------------------------------------------------------- /content/8.interop/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Interoperabilidad' 3 | description: '' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'other' 8 | position: 9 | x: 100 10 | y: 1400 11 | sourcePosition: 12 | concurrency: 'left' 13 | targetPosition: 14 | ecosystem: 'bottom' 15 | --- 16 | # Titulo 17 | -------------------------------------------------------------------------------- /content/9.ecosystem/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Ecosistema y Librerias' 3 | description: '' 4 | draft: true 5 | data: 6 | type: 'custom' 7 | topicLevel: 'other' 8 | position: 9 | x: 100 10 | y: 1800 11 | sourcePosition: 12 | interop: 'top' 13 | targetPosition: 14 | continue: 'bottom' 15 | --- 16 | # Titulo 17 | -------------------------------------------------------------------------------- /content/continue.yml: -------------------------------------------------------------------------------- 1 | title: 'Continua Aprendiendo' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'other' 6 | position: 7 | x: 100 8 | y: 2000 9 | sourcePosition: 10 | ecosystem: 'top' 11 | targetPosition: 12 | none: 'bottom' 13 | -------------------------------------------------------------------------------- /content/rust.yml: -------------------------------------------------------------------------------- 1 | title: 'Rust' 2 | description: '' 3 | data: 4 | type: 'transparent' 5 | topicLevel: 'start' 6 | position: 7 | x: 390 8 | y: -100 9 | sourcePosition: 10 | none: 'top' 11 | targetPosition: 12 | introduction: 'bottom' 13 | -------------------------------------------------------------------------------- /crates/preview/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /crates/preview/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "preview" 3 | version.workspace = true 4 | edition.workspace = true 5 | repository.workspace = true 6 | 7 | [dependencies] 8 | walkdir = "2" 9 | imageproc = "0.25" 10 | ab_glyph = "0.2.28" 11 | image = { version = "0.25", default-features = false, features = ["png"] } 12 | serde = { version = "1", default-features = false, features = ["derive"] } 13 | gray_matter = { version = "0.2", default-features = false, features = ["yaml"] } 14 | -------------------------------------------------------------------------------- /crates/preview/assets/WorkSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/crates/preview/assets/WorkSans-Bold.ttf -------------------------------------------------------------------------------- /crates/preview/assets/WorkSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/crates/preview/assets/WorkSans-Regular.ttf -------------------------------------------------------------------------------- /crates/preview/assets/bg_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/crates/preview/assets/bg_preview.png -------------------------------------------------------------------------------- /crates/preview/src/img.rs: -------------------------------------------------------------------------------- 1 | use std::time::{Duration, Instant}; 2 | 3 | use ab_glyph::FontRef; 4 | use image::{Rgba, RgbaImage}; 5 | 6 | use crate::mdx::FrontMatter; 7 | use crate::render_time; 8 | 9 | const BLACK: Rgba = Rgba([0, 0, 0, 255]); 10 | 11 | pub fn generate_preview( 12 | bg: &RgbaImage, 13 | bold_font: &FontRef, 14 | regular_font: &FontRef, 15 | out: &str, 16 | matter: FrontMatter, 17 | ) -> Duration { 18 | let time = Instant::now(); 19 | let title = matter.title(); 20 | let title = title 21 | .get(..47) 22 | .or_else(|| Some(title)) 23 | .map(|s| { 24 | if s.len() >= 47 { 25 | format!("{s}...") 26 | } else { 27 | s.to_owned() 28 | } 29 | }) 30 | .unwrap(); 31 | let description = matter.description(); 32 | let name = matter.name(); 33 | 34 | let mut img = imageproc::drawing::draw_text(bg, BLACK, 24, 171, 42., bold_font, &title); 35 | 36 | // Description 37 | for (i, s) in chunked_string(description, 45, 8).iter().enumerate() { 38 | imageproc::drawing::draw_text_mut( 39 | &mut img, 40 | BLACK, 41 | 56, 42 | 317 + 28 + (34 * i as i32 + 1), 43 | 34., 44 | regular_font, 45 | &s, 46 | ); 47 | } 48 | 49 | let out = format!("{out}/{name}.png"); 50 | img.save_with_format(&out, image::ImageFormat::Png).unwrap(); 51 | 52 | let time = time.elapsed(); 53 | 54 | println!("Success ({t}): {name} at {out}", t = render_time(time)); 55 | time 56 | } 57 | 58 | pub fn chunked_string(s: &str, line_width: usize, max_lines: usize) -> Vec { 59 | let (lines, last) = s.split_whitespace().fold( 60 | (Vec::new(), String::new()), 61 | |(mut lines, mut current_line), word| { 62 | if current_line.len() + word.len() + (!current_line.is_empty() as usize) > line_width { 63 | if !current_line.is_empty() { 64 | lines.push(current_line); 65 | } 66 | current_line = word.to_string(); 67 | } else { 68 | if !current_line.is_empty() { 69 | current_line.push(' '); 70 | } 71 | current_line.push_str(word); 72 | } 73 | 74 | if lines.len() == max_lines - 1 && !current_line.is_empty() { 75 | lines.push(current_line); 76 | return (lines, String::new()); 77 | } 78 | 79 | (lines, current_line) 80 | }, 81 | ); 82 | lines 83 | .into_iter() 84 | .chain(std::iter::once(last)) 85 | .take(max_lines) 86 | .collect() 87 | } 88 | 89 | #[cfg(test)] 90 | mod tests { 91 | use super::chunked_string; 92 | 93 | #[test] 94 | fn chunks() { 95 | let chunked = chunked_string("El Tipo de Dato `str` en Rust", 50, 8); 96 | assert_eq!(&chunked[..], &["El Tipo de Dato `str` en Rust"]); 97 | 98 | let chunked = chunked_string("Guía de configuracion para los Editores de Texto Más Comunes (Vs Code, Visual Studio, IntelliJ IDEA, Vim, Neovim, Sublime Text)", 50, 8); 99 | assert_eq!( 100 | &chunked[..], 101 | &[ 102 | "Guía de configuracion para los Editores de Texto", 103 | "Más Comunes (Vs Code, Visual Studio, IntelliJ", 104 | "IDEA, Vim, Neovim, Sublime Text)", 105 | ] 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /crates/preview/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use ab_glyph::FontRef; 4 | use gray_matter::engine::YAML; 5 | use gray_matter::Matter; 6 | 7 | use crate::img::generate_preview; 8 | 9 | mod img; 10 | mod mdx; 11 | 12 | const BOLD_FONT: &[u8] = include_bytes!("../assets/WorkSans-Bold.ttf"); 13 | const REGULAR_FONT: &[u8] = include_bytes!("../assets/WorkSans-Regular.ttf"); 14 | 15 | fn main() { 16 | let mut args = std::env::args().skip(1); 17 | 18 | let bg = args 19 | .next() 20 | .expect("The first argument must be the background preset file"); 21 | 22 | let out = args 23 | .next() 24 | .expect("The seconds argument must be the output directory"); 25 | 26 | let files = if args.len() > 1 { 27 | args.collect::>() 28 | } else { 29 | let dir = args.next().expect( 30 | "The third argument must be the directory with the content or files to be processed", 31 | ); 32 | 33 | // get all files recursively on dir 34 | walkdir::WalkDir::new(&dir) 35 | .sort_by_file_name() 36 | .into_iter() 37 | .flat_map(|d| { 38 | let Ok(d) = d else { 39 | return None; 40 | }; 41 | if d.file_type().is_file() && d.path().extension().is_some_and(|e| e != "yml") { 42 | return d.path().to_str().map(|d| d.to_string()); 43 | } 44 | None 45 | }) 46 | .collect() 47 | }; 48 | 49 | let matter = Matter::::new(); 50 | 51 | if std::fs::metadata(&out).is_err() { 52 | println!("Creating directory"); 53 | std::fs::create_dir_all(&out).unwrap(); 54 | } 55 | 56 | let bold_font = FontRef::try_from_slice(BOLD_FONT).unwrap(); 57 | let regular_font = FontRef::try_from_slice(REGULAR_FONT).unwrap(); 58 | let bg = image::open(bg).unwrap().into_rgba8(); 59 | 60 | let res = files 61 | .iter() 62 | .map(|f| { 63 | generate_preview( 64 | &bg, 65 | &bold_font, 66 | ®ular_font, 67 | &out, 68 | mdx::from_file(f.as_str(), &matter), 69 | ) 70 | }) 71 | .collect::>(); 72 | 73 | println!("\nTotal Image Processed: {c}", c = res.len()); 74 | println!("Total: {time}", time = render_time(res.iter().sum())); 75 | println!( 76 | "Max: {time}", 77 | time = render_time(res.clone().into_iter().max().unwrap()) 78 | ); 79 | println!( 80 | "Min: {time}", 81 | time = render_time(res.clone().into_iter().min().unwrap()) 82 | ); 83 | println!( 84 | "Avg: {time}", 85 | time = render_time( 86 | res.iter() 87 | .map(Duration::as_nanos) 88 | .reduce(|acc, x| acc + x) 89 | .map(|total| total / res.len() as u128) 90 | .map(|avg| Duration::from_nanos(avg as u64)) 91 | .unwrap() 92 | ) 93 | ); 94 | } 95 | 96 | pub fn render_time(duration: Duration) -> String { 97 | let seconds = duration.as_secs(); 98 | let milliseconds = duration.subsec_millis(); 99 | let nanoseconds = duration.subsec_nanos(); 100 | 101 | format!("{seconds}s {milliseconds}ms {nanoseconds}ns") 102 | } 103 | -------------------------------------------------------------------------------- /crates/preview/src/mdx.rs: -------------------------------------------------------------------------------- 1 | use gray_matter::engine::YAML; 2 | use gray_matter::Matter; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Serialize, Deserialize)] 6 | pub struct FrontMatter { 7 | title: String, 8 | description: String, 9 | pub draft: bool, 10 | 11 | #[serde(skip)] 12 | name: String, 13 | } 14 | 15 | impl FrontMatter { 16 | pub fn name(&self) -> &str { 17 | &self.name 18 | } 19 | 20 | pub fn title(&self) -> &str { 21 | &self.title 22 | } 23 | 24 | pub fn description(&self) -> &str { 25 | &self.description 26 | } 27 | } 28 | 29 | pub fn from_file(path: &str, matter: &Matter) -> FrontMatter { 30 | let content = std::fs::read_to_string(path).unwrap(); 31 | let raw = matter.parse(&content).data.unwrap().deserialize().unwrap(); 32 | 33 | FrontMatter { 34 | name: path 35 | .replace("./", "") 36 | .replace(".md", "") 37 | .split('/') 38 | .map(|p| p.split('.').skip(1).collect::()) 39 | .collect::>() 40 | .join("-") 41 | .trim_matches('-') 42 | .to_string(), 43 | ..raw 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "fenix": { 4 | "inputs": { 5 | "nixpkgs": "nixpkgs", 6 | "rust-analyzer-src": "rust-analyzer-src" 7 | }, 8 | "locked": { 9 | "lastModified": 1710829337, 10 | "narHash": "sha256-uDsDTHN7hlx1k9OCukv1DQ9LoTXiM6joTXNV+6LLY1E=", 11 | "owner": "nix-community", 12 | "repo": "fenix", 13 | "rev": "c3383b4ebf6191410babd6c11b4be5e295ec69b1", 14 | "type": "github" 15 | }, 16 | "original": { 17 | "owner": "nix-community", 18 | "repo": "fenix", 19 | "type": "github" 20 | } 21 | }, 22 | "flake-utils": { 23 | "inputs": { 24 | "systems": "systems" 25 | }, 26 | "locked": { 27 | "lastModified": 1710146030, 28 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 29 | "owner": "numtide", 30 | "repo": "flake-utils", 31 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 32 | "type": "github" 33 | }, 34 | "original": { 35 | "owner": "numtide", 36 | "repo": "flake-utils", 37 | "type": "github" 38 | } 39 | }, 40 | "nixpkgs": { 41 | "locked": { 42 | "lastModified": 1710631334, 43 | "narHash": "sha256-rL5LSYd85kplL5othxK5lmAtjyMOBg390sGBTb3LRMM=", 44 | "owner": "nixos", 45 | "repo": "nixpkgs", 46 | "rev": "c75037bbf9093a2acb617804ee46320d6d1fea5a", 47 | "type": "github" 48 | }, 49 | "original": { 50 | "owner": "nixos", 51 | "ref": "nixos-unstable", 52 | "repo": "nixpkgs", 53 | "type": "github" 54 | } 55 | }, 56 | "nixpkgs_2": { 57 | "locked": { 58 | "lastModified": 1710806803, 59 | "narHash": "sha256-qrxvLS888pNJFwJdK+hf1wpRCSQcqA6W5+Ox202NDa0=", 60 | "owner": "NixOS", 61 | "repo": "nixpkgs", 62 | "rev": "b06025f1533a1e07b6db3e75151caa155d1c7eb3", 63 | "type": "github" 64 | }, 65 | "original": { 66 | "owner": "NixOS", 67 | "ref": "nixos-unstable", 68 | "repo": "nixpkgs", 69 | "type": "github" 70 | } 71 | }, 72 | "root": { 73 | "inputs": { 74 | "fenix": "fenix", 75 | "flake-utils": "flake-utils", 76 | "nixpkgs": "nixpkgs_2" 77 | } 78 | }, 79 | "rust-analyzer-src": { 80 | "flake": false, 81 | "locked": { 82 | "lastModified": 1710800801, 83 | "narHash": "sha256-MYfxHeKLAhgwgha88ON0SkpNmydpg3Ib93Qny6RQZao=", 84 | "owner": "rust-lang", 85 | "repo": "rust-analyzer", 86 | "rev": "4de0204d58125392aa14d4f224b29f3c54a274e5", 87 | "type": "github" 88 | }, 89 | "original": { 90 | "owner": "rust-lang", 91 | "ref": "nightly", 92 | "repo": "rust-analyzer", 93 | "type": "github" 94 | } 95 | }, 96 | "systems": { 97 | "locked": { 98 | "lastModified": 1681028828, 99 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 100 | "owner": "nix-systems", 101 | "repo": "default", 102 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 103 | "type": "github" 104 | }, 105 | "original": { 106 | "owner": "nix-systems", 107 | "repo": "default", 108 | "type": "github" 109 | } 110 | } 111 | }, 112 | "root": "root", 113 | "version": 7 114 | } 115 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 4 | fenix.url = "github:nix-community/fenix"; 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | }; 7 | 8 | outputs = { 9 | self, 10 | nixpkgs, 11 | flake-utils, 12 | ... 13 | } @ inputs: 14 | flake-utils.lib.eachSystem (flake-utils.lib.defaultSystems) ( 15 | system: let 16 | pkgs = nixpkgs.legacyPackages.${system}; 17 | fenix = inputs.fenix.packages; 18 | # fenix: rustup replacement for reproducible builds 19 | toolchain = fenix.${system}.fromToolchainFile { 20 | file = ./rust-toolchain.toml; 21 | sha256 = "sha256-Ngiz76YP4HTY75GGdH2P+APE/DEIx2R/Dn+BwwOyzZU="; 22 | }; 23 | in { 24 | # `nix develop` 25 | devShells.default = pkgs.mkShell { 26 | packages = with pkgs; [ 27 | toolchain 28 | pkg-config 29 | cargo-dist 30 | git-cliff 31 | ]; 32 | }; 33 | } 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /generateContentRoutes.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs').promises; 2 | const path = require('path'); 3 | 4 | const contentDir = path.join(process.cwd(), 'content'); 5 | 6 | async function walkDir(dir) { 7 | let filesList = []; 8 | const files = await fs.readdir(dir, { withFileTypes: true }); 9 | for (const file of files) { 10 | const res = path.resolve(dir, file.name); 11 | if (file.isDirectory()) { 12 | filesList = filesList.concat(await walkDir(res)); 13 | } else if (file.isFile() && path.extname(file.name).toLowerCase() === '.md' || path.extname(file.name) != 'yml') { 14 | filesList.push(res); 15 | } 16 | } 17 | return filesList; 18 | } 19 | 20 | function filePathToRoute(filePath) { 21 | let route = filePath 22 | .replace(contentDir, '') 23 | .replace(/\.md$/, '') 24 | .replace(/\\/g, '/'); // Reemplazar backslashes con forward slashes para compatibilidad 25 | 26 | // Manejar index.md 27 | if (route.endsWith('/index')) { 28 | route = route.replace('/index', ''); 29 | } 30 | 31 | // Manejar _dir.md (directorios) 32 | route = route.replace(/\/_([^/]+)/g, ''); 33 | 34 | // Eliminar números al inicio de los segmentos de la ruta 35 | route = route.split('/').map(segment => segment.replace(/^\d+\./, '')).join('/'); 36 | 37 | // Asegurarse de que la ruta comience con '/' 38 | if (!route.startsWith('/')) { 39 | route = '/' + route; 40 | } 41 | 42 | return route || '/'; 43 | } 44 | 45 | async function generateContentRoutes() { 46 | const filePaths = await walkDir(contentDir); 47 | const routes = filePaths.map(filePath => filePathToRoute(filePath)); 48 | return routes; 49 | } 50 | 51 | generateContentRoutes() 52 | .then(routes => { 53 | console.log('Content Routes:'); 54 | console.log(JSON.stringify(routes, null, 2)); 55 | }) 56 | .catch(error => { 57 | console.error('Error generating routes:', error); 58 | }); 59 | 60 | module.exports = generateContentRoutes; 61 | -------------------------------------------------------------------------------- /index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /layouts/hero.vue: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /nuxt.config.ts: -------------------------------------------------------------------------------- 1 | const generateContentRoutes = require('./generateContentRoutes'); 2 | 3 | // https://nuxt.com/docs/api/configuration/nuxt-config 4 | export default defineNuxtConfig({ 5 | devtools: { enabled: true }, 6 | modules: ["@nuxt/content", "@nuxtjs/tailwindcss", "@nuxtjs/seo"], 7 | site: { 8 | url: 'https://roadmap.rustlang-es.org', 9 | name: 'Hoja de Ruta Definitiva para Aprender Rust', 10 | description: 'Nuestra hoja de ruta te guiará paso a paso en tu viaje de aprendizaje de Rust diseñada para principiantes y desarrolladores experimentados', 11 | defaultLocale: 'es' 12 | }, 13 | ogImage: { enabled: false }, 14 | nitro: { 15 | prerender: { 16 | routes: ['/sitemap.xml'], 17 | } 18 | }, 19 | app: { 20 | head: { 21 | charset: 'utf-8', 22 | viewport: 'width=device-width, initial-scale=1', 23 | link: [ 24 | { rel: "preconnect", href:"https://fonts.googleapis.com" }, 25 | { rel: "preconnect", href:"https://fonts.gstatic.com", crossorigin: true }, 26 | { rel: 'stylesheet', href:"https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" }, 27 | { rel: 'stylesheet', href:"https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Work+Sans:ital,wght@0,100..900;1,100..900&display=swap" }, 28 | ] 29 | } 30 | }, 31 | content: { 32 | highlight: { 33 | langs: ['c', 'cpp', 'rs', 'java', 'js', 'cs', 'asm', 'toml', 'console', 'sh', 'bash', "vim"], 34 | // Themes from https://github.com/shikijs/textmate-grammars-themes/tree/main/packages/tm-themes 35 | theme: { 36 | default: 'vitesse-dark', 37 | dark: 'vitesse-dark', 38 | sepia: 'monokai' 39 | } 40 | }, 41 | }, 42 | hooks: { 43 | async 'prerender:routes'(ctx) { 44 | const contentRoutes = await generateContentRoutes(); 45 | 46 | for (const route of contentRoutes) { 47 | ctx.routes.add(route) 48 | } 49 | } 50 | } 51 | }) 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-app", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "@nuxt/content": "^2.12.1", 14 | "@vue-flow/controls": "^1.1.1", 15 | "@vue-flow/core": "^1.33.6", 16 | "@vue-flow/minimap": "^1.4.0", 17 | "nuxt": "^3.11.2", 18 | "sitemap": "^8.0.0", 19 | "v-dropdown": "^3.0.0", 20 | "vue": "^3.4.21", 21 | "vue-router": "^4.3.0" 22 | }, 23 | "devDependencies": { 24 | "@nuxtjs/seo": "^2.0.0-rc.10", 25 | "@nuxtjs/tailwindcss": "^6.12.0", 26 | "@tailwindcss/typography": "^0.5.13", 27 | "@unocss/nuxt": "^0.60.0" 28 | }, 29 | "trustedDependencies": [ 30 | "@fortawesome/fontawesome-common-types", 31 | "@fortawesome/free-regular-svg-icons", 32 | "@fortawesome/free-solid-svg-icons", 33 | "json-editor-vue" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /pages/[...slug].vue: -------------------------------------------------------------------------------- 1 | 75 | 76 | 122 | 123 | 128 | -------------------------------------------------------------------------------- /plugins/locally.js: -------------------------------------------------------------------------------- 1 | export default defineNuxtPlugin(() => { 2 | return { 3 | provide: { 4 | locally: { 5 | get(item) { 6 | return localStorage.getItem(item) 7 | }, 8 | 9 | set(item, value) { 10 | return localStorage.setItem(item, value) 11 | } 12 | } 13 | } 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/favicon.ico -------------------------------------------------------------------------------- /public/previews/basic-array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-array.png -------------------------------------------------------------------------------- /public/previews/basic-boolean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-boolean.png -------------------------------------------------------------------------------- /public/previews/basic-char.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-char.png -------------------------------------------------------------------------------- /public/previews/basic-const-and-statics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-const-and-statics.png -------------------------------------------------------------------------------- /public/previews/basic-control-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-control-flow.png -------------------------------------------------------------------------------- /public/previews/basic-enum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-enum.png -------------------------------------------------------------------------------- /public/previews/basic-float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-float.png -------------------------------------------------------------------------------- /public/previews/basic-function-clousures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-function-clousures.png -------------------------------------------------------------------------------- /public/previews/basic-hashmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-hashmap.png -------------------------------------------------------------------------------- /public/previews/basic-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-index.png -------------------------------------------------------------------------------- /public/previews/basic-lifetimes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-lifetimes.png -------------------------------------------------------------------------------- /public/previews/basic-ownership-borrowing-concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-ownership-borrowing-concept.png -------------------------------------------------------------------------------- /public/previews/basic-pattern-matching.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-pattern-matching.png -------------------------------------------------------------------------------- /public/previews/basic-range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-range.png -------------------------------------------------------------------------------- /public/previews/basic-reference-and-mutability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-reference-and-mutability.png -------------------------------------------------------------------------------- /public/previews/basic-shadowing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-shadowing.png -------------------------------------------------------------------------------- /public/previews/basic-signed-integer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-signed-integer.png -------------------------------------------------------------------------------- /public/previews/basic-slices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-slices.png -------------------------------------------------------------------------------- /public/previews/basic-str.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-str.png -------------------------------------------------------------------------------- /public/previews/basic-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-string.png -------------------------------------------------------------------------------- /public/previews/basic-struct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-struct.png -------------------------------------------------------------------------------- /public/previews/basic-temporary-borrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-temporary-borrow.png -------------------------------------------------------------------------------- /public/previews/basic-transfer-ownership.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-transfer-ownership.png -------------------------------------------------------------------------------- /public/previews/basic-tuples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-tuples.png -------------------------------------------------------------------------------- /public/previews/basic-unsigned-integer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-unsigned-integer.png -------------------------------------------------------------------------------- /public/previews/basic-variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-variables.png -------------------------------------------------------------------------------- /public/previews/basic-vector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/basic-vector.png -------------------------------------------------------------------------------- /public/previews/cargo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/cargo.png -------------------------------------------------------------------------------- /public/previews/concurrency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/concurrency.png -------------------------------------------------------------------------------- /public/previews/ecosystem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/ecosystem.png -------------------------------------------------------------------------------- /public/previews/error-handling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/error-handling.png -------------------------------------------------------------------------------- /public/previews/interop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/interop.png -------------------------------------------------------------------------------- /public/previews/introduction-code-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-code-editor.png -------------------------------------------------------------------------------- /public/previews/introduction-first-program.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-first-program.png -------------------------------------------------------------------------------- /public/previews/introduction-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-index.png -------------------------------------------------------------------------------- /public/previews/introduction-install-rust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-install-rust.png -------------------------------------------------------------------------------- /public/previews/introduction-rust-channels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-rust-channels.png -------------------------------------------------------------------------------- /public/previews/introduction-why-rust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/introduction-why-rust.png -------------------------------------------------------------------------------- /public/previews/ogpreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/ogpreview.png -------------------------------------------------------------------------------- /public/previews/smart-pointers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/smart-pointers.png -------------------------------------------------------------------------------- /public/previews/traits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustLangES/rustmap/e8d905e6a0d285b1377286dbaab7287ca251bf00/public/previews/traits.png -------------------------------------------------------------------------------- /release.toml: -------------------------------------------------------------------------------- 1 | allow-branch = ["main", "dev", "!HEAD"] 2 | publish = false 3 | pre-release-commit-message = "release: preview version {{version}}" 4 | tag-prefix = "gen_preview/" 5 | tag-name = "v{{version}}" 6 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | profile = "minimal" 4 | -------------------------------------------------------------------------------- /sc.toml: -------------------------------------------------------------------------------- 1 | # this use https://github.com/romancitodev/simple-commits 2 | 3 | [git] 4 | skip_preview = true 5 | skip_emojis = true 6 | 7 | [[scopes]] 8 | name = "manifest" 9 | description = "Configuration files for the project, including Cargo.toml and related." 10 | 11 | [[scopes]] 12 | name = "docs" 13 | description = "Documentation files for the project, such as README or tutorials." 14 | 15 | [[scopes]] 16 | name = "nix" 17 | description = "Nix configuration files for reproducible builds." 18 | 19 | [[scopes]] 20 | name = "preview" 21 | description = "Preview generation logic and related configurations." 22 | 23 | # Content-related scopes 24 | [[scopes]] 25 | name = "content:introduction" 26 | description = "Introduction section in the project's content." 27 | 28 | [[scopes]] 29 | name = "content:basic" 30 | description = "Basic concepts and examples in the project's content." 31 | 32 | [[scopes]] 33 | name = "content:error-handling" 34 | description = "Error handling concepts in the project's content." 35 | 36 | [[scopes]] 37 | name = "content:cargo" 38 | description = "Cargo-related content in the documentation or guides." 39 | 40 | [[scopes]] 41 | name = "content:traits" 42 | description = "Content related to Rust traits and their usage." 43 | 44 | [[scopes]] 45 | name = "content:smart-pointers" 46 | description = "Documentation about Rust smart pointers and their examples." 47 | 48 | [[scopes]] 49 | name = "content:concurrency" 50 | description = "Concurrency concepts and examples in the documentation." 51 | 52 | [[scopes]] 53 | name = "content:interop" 54 | description = "Interoperability guides for Rust with other languages or tools." 55 | 56 | [[scopes]] 57 | name = "content:ecosystem" 58 | description = "Documentation about the Rust ecosystem and external crates." 59 | 60 | # UI-related scopes 61 | [[scopes]] 62 | name = "ui:components" 63 | description = "Reusable components in the project's user interface." 64 | 65 | [[scopes]] 66 | name = "ui:design" 67 | description = "Design-related aspects of the project's UI." 68 | -------------------------------------------------------------------------------- /server/routes/sitemap.xml.ts: -------------------------------------------------------------------------------- 1 | import { serverQueryContent } from '#content/server' 2 | import { SitemapStream, streamToPromise } from 'sitemap' 3 | 4 | export default defineEventHandler(async (event) => { 5 | // Fetch all documents 6 | const articles = await serverQueryContent(event).find() 7 | const sitemap = new SitemapStream({ hostname: 'https://roadmap.rustlang-es.org/' }) 8 | 9 | console.log(articles) 10 | 11 | articles.forEach(article => sitemap.write({ url: article._path, img: [ { 12 | url: `https://roadmap.rustlang-es.org/previews/${article._path.substring(1).replaceAll('/', "-")}.png`, 13 | caption: article.description, 14 | title: article.title, 15 | }, ] })) 16 | sitemap.end() 17 | 18 | return (await streamToPromise(sitemap)) 19 | }) 20 | -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | plugins: [ 4 | require('@tailwindcss/typography'), 5 | ], 6 | theme: { 7 | fontFamily: { 8 | "alfa-slab": ["Alfa Slab One", "sans-serif"], 9 | "fira-sans": ["Fira Sans", "sans-serif"], 10 | "work-sans": ["Work Sans", "sans-serif"], 11 | }, 12 | extend: { 13 | fontSize: { 14 | 'half': '3.5rem', 15 | }, 16 | lineHeight: { 17 | '3lh': '2.8rem', 18 | }, 19 | backgroundImage: (theme) => ({ 20 | "anuncios": "url('https://i.imgur.com/tDlT9sr.jpg')", 21 | "kaku-dev": "url('https://www.rustlang-es.org/kaku.avif')", 22 | "kaku": "url('https://www.rustlang-es.org/kaku.avif')", 23 | }), 24 | }, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json", 4 | "compilerOptions": { 5 | "typeRoots": ["./types"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /types/roadmapSidebar.ts: -------------------------------------------------------------------------------- 1 | export type RoadmapSidebar = { 2 | title: String; 3 | slug: String; 4 | } 5 | -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "roadmap" 2 | main = "./.output/server/index.mjs" 3 | workers_dev = true 4 | compatibility_date = "2024-03-14" 5 | 6 | rules = [ 7 | { type = "ESModule", globs = ["**/*.js", "**/*.mjs"]}, 8 | ] 9 | 10 | [site] 11 | bucket = ".output/public" 12 | --------------------------------------------------------------------------------